由于x86下用于计算fsin
函数的函数sin(x)
可以追溯到奔腾时代,而且显然甚至不使用SSE寄存器,因此我想知道是否有一套更新更好的指令来计算三角函数。
我曾经用C++编写代码并做了一些asm
优化,所以适合从C++到C到asm的管道中的任何事情都可以为我做。
谢谢。
我现在使用gcc
和clang
在Linux 64位下(即使强硬的clang并没有真正提供任何与FPU相关的优化AFAIK)。
编辑
sin
函数,即使启用了std::sin
,它通常比sse
快2倍。 fsin
慢,即使强悍的fsin
通常也更准确,但是考虑到fsin
永远不会超过sin
实现,我现在将保留sin
,而且sin
完全可移植,其中fsin
仅适用于x86。 最佳答案
如果需要为-π…π上的绝对精度优化的正弦近似值,请使用:
x *(1 + x * x *(-0.1661251158026961831813227851437597220432 + x * x *(8.03943560729777477481878247432892823523524338e-3 + x * x * -1.4941402004593877749503989396238510717e-4)))
它可以通过以下方式实现:
float xx = x * x;
float s = x + (x * xx) * (-0.16612511580269618f + xx * (8.0394356072977748e-3f + xx * -1.49414020045938777495e-4f));
也许是optimized depending on the characteristics of your target architecture。另外,在链接的博客文章中未注明,如果要在程序集中实现,请使用
FMADD
指令。如果以C或C++实现,则使用fmaf()
C99标准函数,请确保已生成FMADD
。仿真版本比乘法和加法要昂贵得多,因为fmaf()
所做的并不完全等同于乘法加法(因此仅实现它是不正确的)。sin(x)与-π和π图之间的上述多项式之间的差异如下:
多项式是优化的,以减小它与-π和π之间的sin(x)之差,而不仅仅是有人认为是个好主意的东西。
如果只需要[-1…1]定义区间,则可以通过忽略其余区间使该区间上的多项式更加精确。在此定义间隔内再次运行the optimization algorithm会产生:
x *(1 + x * x *(-1.666659904470470566774477504230733785739156e-1 + x * x *(8.329797530524482484880881032235130130746746e-3 + x * x *(-1.928379009208489415662312713847811393721e-4)))
绝对误差图:
如果这对您来说太准确了,则可以使用optimize a polynomial of lower degree for the same objective。这样,绝对误差会更大,但您将保存一个或两个乘法。
关于c++ - 更快但不那么准确的Intel ASM的fsin?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23837916/