由于x86下用于计算fsin函数的函数sin(x)可以追溯到奔腾时代,而且显然甚至不使用SSE寄存器,因此我想知道是否有一套更新更好的指令来计算三角函数。

我曾经用C++编写代码并做了一些asm优化,所以适合从C++到C到asm的管道中的任何事情都可以为我做。

谢谢。

我现在使用gccclang在Linux 64位下(即使强硬的clang并没有真正提供任何与FPU相关的优化AFAIK)。

编辑

  • 我已经实现了sin函数,即使启用了std::sin,它通常比sse快2倍。
  • 我的功能从来没有比fsin慢,即使强悍的fsin通常也更准确,但是考虑到fsin永远不会超过sin实现,我现在将保留sin,而且sin完全可移植,其中fsin仅适用于x86。
  • 我需要此来进行实时计算,因此我将精度换成速度,我认为4-5位小数的精度会很好。
  • 不支持基于表的方法,我没有使用它,它搞砸了缓存,使一切变慢了,请不要基于内存访问或查找表的算法。
  • 最佳答案

    如果需要为-π…π上的绝对精度优化的正弦近似值,请使用:

    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/

    10-09 18:00