C++ Newton Raphson和SSE2-有人能给我解释一下这三行吗

C++ Newton Raphson和SSE2-有人能给我解释一下这三行吗,c++,c,math,sse,newtons-method,C++,C,Math,Sse,Newtons Method,我正在阅读这份文件: 我偶然发现了这三行代码: SIMD版本已经快了很多,但我们可以做得更好。 英特尔在SSE2指令集中添加了一个快速1/sqrt(x)函数。 唯一的缺点是其精度有限。我们需要 精度,因此我们使用Newton Rhapson对其进行细化: 此代码假定存在名为“half”的_m128变量 (四乘以0.5f)和一个变量“三”(四乘以3.0f) 我知道如何使用Newton Raphson来计算函数的零,我知道如何使用它来计算数字的平方根,但我看不出这段代码是如何执行的 有人能给我解释一

我正在阅读这份文件:

我偶然发现了这三行代码:

SIMD版本已经快了很多,但我们可以做得更好。 英特尔在SSE2指令集中添加了一个快速1/sqrt(x)函数。 唯一的缺点是其精度有限。我们需要 精度,因此我们使用Newton Rhapson对其进行细化:

此代码假定存在名为“half”的_m128变量 (四乘以0.5f)和一个变量“三”(四乘以3.0f)

我知道如何使用Newton Raphson来计算函数的零,我知道如何使用它来计算数字的平方根,但我看不出这段代码是如何执行的


有人能给我解释一下吗?

考虑到牛顿迭代法,在源代码中看到这一点应该很简单

 __m128 nr   = _mm_rsqrt_ps( x );                  // The initial approximation y_0
 __m128 muls = _mm_mul_ps( _mm_mul_ps( x, nr ), nr ); // muls = x*nr*nr == x(y_n)^2
 result = _mm_mul_ps(
               _mm_sub_ps( three, muls )    // this is 3.0 - mul;
   /*multiplied by */ __mm_mul_ps(half,nr)  // y_0 / 2 or y_0 * 0.5
 );
准确地说,这个算法是为

注意这一点
rsqrtps
与NR迭代相比,精度几乎达到23位,而
sqrtps
的24位精度为最后一位的正确舍入


如果你想的话,精确度有限是个问题<代码>(int)4.99999是
4
。另外,如果使用
sqrt(x)~=x*sqrt(x)
,请注意
x==0.0
的情况,因为
0*+Inf=NaN
要计算
a
的逆平方根,牛顿方法应用于方程
0=f(x)=a-x^(-2)
和导数
f'(x)=2*x^(-3)

N(x) = x - f(x)/f'(x) = x - (a*x^3-x)/2 
     = x/2 * (3 - a*x^2)

与全局收敛相比,这种无除法具有有限的收敛区域,因此需要对平方根反比进行良好的近似,以获得更好的近似值。

当截断为整数时,您认为作为最后一步,添加一个与结果具有相同指数但仅在有效位中设置最低一位(或两位?)的值是否可行?这当然是在最低有效数字总是低于其位置的情况下,这取决于应用程序。关键是当使用迭代方法时,
sqrt(n*n)==n
并不总是成立的。这不能任意“修复”——因为
sqrt(n*n-epsilon)=n
可能导致灾难。
N(x) = x - f(x)/f'(x) = x - (a*x^3-x)/2 
     = x/2 * (3 - a*x^2)