1

所以最近我偶然发现了这样的快速逆平方根算法。

float inverse_rsqrt( float number )
{
    const float threehalfs = 1.5F;
    float x2 = number * 0.5F;
    float y = number;
    long i = * ( long * ) &y;
    i = 0x5f3759df - ( i >> 1 );
    y = * ( float * ) &i;
    y = y * ( threehalfs - ( x2 * y * y ) );
  
    return y;

我认为这是对我的 Ray Tracer 的一个很好的优化,因为我必须规范化很多向量,我只需要切换出这段代码。

Vec3D normalize(Vec3D vector){
    return vector/(sqrt((vector[0]*vector[0])+(vector[1]*vector[1])+(vector[2]*vector[2])));
}

但是,当我实现代码时,它最终会花费相同的时间。这是我使用的实现。

Vec3D normalize(const Vec3D& rhs) {     // Normalize Vector

      float num = rhs[0]*rhs[0]+rhs[1]*rhs[1]+rhs[2]*rhs[2];
      const float threehalfs = 1.5F;
      float y = num;
      long i = * (long *) &y;
    
      i = 0x5f3759df - (i >> 1);
      y = * (float *) &i;
    
      y = y*(threehalfs - ((num*0.5F)*y*y));
    
      return rhs*y;

我想知道标准 c++ cmath 库中的 sqrt 函数是否与快速逆平方根算法一样好,或者可能不是,我错过了一个关键细节。

注意:Vec3D 只是一个大小为 3 的向量,它具有 x、y、z 参数,并且我重载了 * 运算符,以便当双精度数乘以向量时,它采用向量的标量倍数。

4

1 回答 1

1

很有可能您的编译器甚至不使用 std::sqrt. 是的,你写的,但是这个规范化操作是一个众所周知的可以硬件加速的操作。x86 现在有一个内置的逆平方,所以它不仅可以节省平方根,还可以用乘法代替除法。

于 2021-04-26T08:50:42.623 回答