用avx256编码acos吗?

jue*_*rgi 1 trigonometry intrinsics avx2

我必须为图像的每个像素调用acos方法。

我正在使用avx2。

除了intel c ++编译器随附的库之外,是否还有_mm256代码用于acos?

har*_*old 5

超过0.0 .. 1.0的反余弦看起来sqrt(1 - x) * pi/2当然不是完全正确,但是这里乘以多项式x来补偿:

__m256 acos(__m256 x) {
    __m256 xp = _mm256_and_ps(x, _mm256_castsi256_ps(_mm256_set1_epi32(0x7FFFFFFF)));
    // main shape
    __m256 one = _mm256_set1_ps(1.0);
    __m256 t = _mm256_sqrt_ps(_mm256_sub_ps(one, xp));
    // polynomial correction factor based on xp
    __m256 c3 = _mm256_set1_ps(-0.02007522);
    __m256 c2 = _mm256_fmadd_ps(xp, c3, _mm256_set1_ps(0.07590315));
    __m256 c1 = _mm256_fmadd_ps(xp, c2, _mm256_set1_ps(-0.2126757));
    __m256 c0 = _mm256_fmadd_ps(xp, c1, _mm256_set1_ps(1.5707963267948966));
    // positive result
    __m256 p = _mm256_mul_ps(t, c0);
    // correct for negative x
    __m256 n = _mm256_sub_ps(_mm256_set1_ps(3.14159265359), p);
    return _mm256_blendv_ps(p, n, x);
}
Run Code Online (Sandbox Code Playgroud)

多项式是通过将第0个系数固定为pi / 2并应用最小二乘拟合来找到其他多项式。因此,它不是最小最大值多项式,并且可能会找到更好的多项式。我已将它与std::acosfMSVC2017 进行了详尽的比较(尽管std::acosf未指定其准确性)。最大绝对误差为8.45194e-05,例如发生在0.106028。最大相对误差为1.87481e-04,最大误差接近(但不等于1)。