c語言快速開平方常數的不完全優化報告


c語言快速開平方常數的不完全優化報告

文章插圖
c語言快速開平方常數的不完全優化報告


原始程序采用C1=0x5f3759df , 本文采用C2=0x5f352267 , 
在對1-256之內的小數進行開平方時 , 測試報告如下:
程序外循環10000次*內循環256次、人工執行exe程序60次的結果:
C1=0x5f3759df19.48333333 ms
C2=0x5f35226719.28333333 ms
normal_c_sqrtf20.43333333 ms
分別一次牛頓迭代 , 相對c語言sqrtf計算結果的精度:
C1=0x5f3759df1.00098
C2=0x5f3522671.00073
在測試范圍內 , C2速度及精度略優 。
值得說明的是 , 對于更大的數的開平方運算是否更優 , 尚需要進一步設置測試程序驗證 。
總體來說快速開平方時間上基本上無差別 , 相比c語言自身提供的函數 , 速度約提高5%左右 , 不知道c語言函數是否已經采用了快速開平方的運算方法 , 還沒有仔細地去查看 。


參考代碼如下:
#include
#include
#include
#include
float Q_rsqrt(float x)
{
long i;
float xhalf;
xhalf=x*0.5f;
i=*(long *)&x;
i=0x5f3759df-(i>>1); //原始常數
x=*(float *)&i;
x=x*(1.5f-(xhalf*x*x));
//x=x*(1.5f-(xhalf*x*x));
return 1.0f/x;
}
float Q_rsqrt_fast(float x)
{
long i;
float xhalf,y;
xhalf=x*0.5f;
i=*(long *)&x;
i=0x5f352267 -(i>>1); //本文常數
x=*(float *)&i;
x=x*(1.5f-(xhalf*x*x));
//x=x*(1.5f-(xhalf*x*x));
return 1.0f/x;


}
int main(int argc,char *argv[])
{
float ary0[300];
float ary1[300];
float ary2[300];


SYSTEMTIME t0;
GetSystemTime(&t0);
for(int j=0;j<10000;j++)
{
for(int i=1;i<=256;i++)
【c語言快速開平方常數的不完全優化報告】{
ary0[i-1]=Q_rsqrt(i+0.5);
}
}


SYSTEMTIME t1;
GetSystemTime(&t1);
for(int j=0;j<10000;j++)
{
for(int i=1;i<=256;i++)
{
ary1[i-1]=Q_rsqrt_fast(i+0.5);
}
}


SYSTEMTIME t2;
GetSystemTime(&t2);
for(int j=0;j<10000;j++)
{
for(int i=1;i<=256;i++)
{
ary2[i-1]=sqrtf(i+0.5);
}
}
SYSTEMTIME t3;
GetSystemTime(&t3);


printf("C1=0x5f3759df time1=%u C2=0x5f352267 time2=%u normalsqrtf time3=%un", t1.wSecond*1000+t1.wMilliseconds-t0.wMilliseconds-t0.wSecond*1000,
t2.wSecond*1000+t2.wMilliseconds-t1.wMilliseconds-t1.wSecond*1000,t3.wSecond*1000+t3.wMilliseconds-t2.wMilliseconds-t2.wSecond*1000);
float f1=0,f2=0;
for(int i=0;i<256;i++)
{
f1+=ary0[i]/ary2[i];
f2+=ary1[i]/ary2[i];
}
printf("C1=0x5f3759df p1=%.5f C2=0x5f352267 p2=%.5fn", f1/256.0,f2/256.0);
return 0;
}


    以上關于本文的內容,僅作參考!溫馨提示:如遇健康、疾病相關的問題,請您及時就醫或請專業人士給予相關指導!

    「愛刨根生活網」www.malaban59.cn小編還為您精選了以下內容,希望對您有所幫助: