计算机系统应用教程网站

网站首页 > 技术文章 正文

c语言快速开平方常数的不完全优化报告

btikc 2024-09-03 11:32:59 技术文章 15 ℃ 0 评论

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 <stdio.h>

#include <math.h>

#include <stdlib.h>

#include <windows.h>

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++)

{

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=%u\n", 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=%.5f\n", f1/256.0,f2/256.0);

return 0;

}

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表