編程中,在對某一向量進行歸一化時,經常需要做上圖中的運算, 翻譯為代碼就是:
y = 1.0 / sqrt(x);
平方根倒數速算法(Fast Inverse Square Root)是一種用于快速計算逆平方根的算法。
其原理是将先将浮點數當作整數位移,再與神奇數字(0x5f3759df)做減法,這樣得到的浮點數結果即是對輸入數字的平方根倒數的粗略估計值,最後再進行一次牛頓叠代法,以使之更精确。
該算法最早來源于一款雷神之錘3的遊戲,據說比用sqrt()函數的效率要高四倍,但我實際測試下來卻發現并非如此,兩者的耗時非常接近,可能和不同的硬件、編譯器、sqrt()庫函數的實現相關,附上測試源碼如下:
#include <stdio.h>
#include <time.h>
#include <math.h>
#include <stdint.h>
float FastInvSqrt(float number)
{
const float half = number * 0.5F;
union {
float f;
uint32_t i;
} conv = {.f = number};
conv.i = 0x5f3759df - (conv.i >> 1);
conv.f *= 1.5F - (half * conv.f * conv.f);
return conv.f;
}
int main()
{
clock_t clock1, clock2;
float x, result, t1, t2;
// 1.0 / sqrt()
clock1 = clock();
x = 0.0;
while (x < 10000.0) {
x = 0.001;
result = 1.0 / sqrt(x);
}
clock2 = clock();
t1 = (float)(clock2 - clock1) / (CLOCKS_PER_SEC) * 1000;
printf("1.0 / sqrt(x) : %f ms\n", t1);
// FastInvSqrt()
clock1 = clock();
x = 0.0;
while (x < 10000.0) {
x = 0.001;
result = FastInvSqrt(x);
}
clock2 = clock();
t2 = (float)(clock2 - clock1) / (CLOCKS_PER_SEC) * 1000;
printf("FastInvSqrt(x) : %f ms\n", t2);
return 0;
}
本地電腦的測試結果如下:
更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!