so recently I stumbled upon the fast inverse square root algorithm that goes like this.
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;
I thought of it as a great optimization to my Ray Tracer as I have to normalize a lot of vectors, and I would just have to switch out this bit of code.
Vec3D normalize(Vec3D vector){
return vector/(sqrt((vector[0]*vector[0])+(vector[1]*vector[1])+(vector[2]*vector[2])));
}
However, when I implemented the code it ends up taking the same amount of time. Here is the implementation I use.
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;
I was wondering if the sqrt function in the standard c++ cmath library is just as good as the fast inverse square root algorithm or maybe it isn't and I'm missing a key detail.
note: Vec3D is just a vector of size three that has x, y, z parameters, and I overloaded the * operator so that when a double is multiplied by a vector it takes the scalar multiple of the vector.
Chances are that your compiler doesn't even use
std::sqrt
. Yes, you wrote it, but this normalize operation is a well-known operation that can be hardware-accelerated. x86 has a built-in inverse sqrt nowadays, so that saves you not just the square root but it also replaces a division by a multiplication.