lve*_*lla 7 c++ floating-point trigonometry
有s一些(未知)角度"a"的正弦,获得"余弦"的最快方法是什么?
我知道两种不同的方式:
c = cos(asin(s));
Run Code Online (Sandbox Code Playgroud)
和
c = sqrt(1 - s*s);
Run Code Online (Sandbox Code Playgroud)
但我不知道函数cos(),asin()和sqrt()的实现如何在速度方面相互比较.一个人比另一个人快多快?它们在现代处理器中的实现之间是否存在显着差异,例如,在x86-64和带VFP的ARM之间?最后,什么是更好的解决方案?
编辑:由于现在已经有3个不相关的答案,让我澄清一下:我最初没有这个角度,我只有正弦.所以没有必要告诉我将角度旋转90度所以我将从另一个函数获得相同的值...
这是一种方式:
sin(a)^ 2 + cos(a)^ 2 = 1(毕达哥拉斯)
cos(a)= sqrt(1 - sin(a)^ 2))
你需要找出不同的象限(即cos()的符号分开).如果您拥有的是sin()值(不同的角度可以具有相同的sin()但cos()因符号而异),则这是不可能的.
正如其他人所指出的,查找表实际上可能是最快的.取决于您需要的精度.这几乎肯定会比你的cos(asin())版本更快,并且平方根也可以在实践中进行优化.
使用Visual Studio 2010,此方法的性能比我的Core i3笔记本电脑上的基于trig的版本(具有快速浮点选项)快约6倍(每次调用大约20ns).我们来看看生成的代码:
快速浮点选项,使用平方根:
; 15 : return sqrt(1.0 - s*s);
movsd xmm1, QWORD PTR __real@3ff0000000000000
mulsd xmm0, xmm0
subsd xmm1, xmm0
sqrtsd xmm0, xmm1
Run Code Online (Sandbox Code Playgroud)
使用trig函数:
; 22 : return cos(asin(s));
call ___libm_sse2_asin
jmp ___libm_sse2_cos
Run Code Online (Sandbox Code Playgroud)
切换到精确浮点模式时,生成的触发代码使用不同的功能(可能是SSE优化版本牺牲精度):
fld QWORD PTR _angle_sin$[esp+esi+65600]
call __CIasin
call __CIcos
fstp QWORD PTR _angle_cos$[esp+esi+65600]
Run Code Online (Sandbox Code Playgroud)