定点算法值得我麻烦吗?

Tho*_*mas 12 floating-point performance x86 fixed-point

我正在研究一种应该实时运行的流体动力学Navier-Stokes求解器.因此,表现很重要.

现在,我正在研究一些紧密的循环,每个循环占执行时间的很大一部分:没有单一的瓶颈.这些循环中的大多数都进行了一些浮点运算,但是它们之间存在很多分支.

浮点运算主要限于加法,减法,乘法,除法和比较.所有这些都是使用32位浮点数完成的.我的目标平台是x86,至少有SSE1指令.(我在汇编器输出中验证了编译器确实生成了SSE指令.)

我正在使用的大多数浮点值具有相当小的上限,而接近零值的精度并不是非常重要.所以我想到了这样的想法:也许转换到定点算法会加快速度?我知道唯一可以确定的方法是测量它,可能需要数天,所以我想事先了解成功的可能性.

在Doom的时代,定点已经风靡一时,但我不确定它在2010年的位置.考虑到现在有多少芯片被用于浮点性能,是否有可能定点运算仍然存在给我一个显着的速度提升?有没有人有任何可能适用于我的情况的实际经验?

Pau*_*l R 6

坚持浮点.固定点实际上只有在8位或16位工作并且使用SIMD(图像处理和音频是典型用例)时才有用.

现代CPU通常有2个FPU,每个时钟周期最多可以发出2个FP指令.然后,您还可以使用4路FP SIMD(SSE)进行优化.

如果您仍然在努力获得良好的性能,那么请尝试使用更好的编译器,例如Intel的ICC.此外,由于64位模型中的寄存器数量增加,64位英特尔可执行文件往往比32位英特尔可执行文件快一些,因此如果可以,则构建64位.

当然,您也应该对您的代码进行分析,以便确定热点所在的位置.你没有说你正在使用什么操作系统,但Windows 上的VTune,Linux 上的Zoom或Mac OS X 上的Shark都将帮助您快速轻松地找到性能瓶颈.


cel*_*ion 3

正如其他人所说,如果您已经在使用浮点 SIMD,我怀疑定点会带来很大的改进。

您说编译器正在发出 SSE 指令,但听起来您并没有尝试编写矢量化 SSE 代码。我不知道编译器通常在这方面做得有多好,但这是值得研究的事情。

另外两个需要关注的领域是:

  1. 内存访问- 如果所有计算都在 SSE 中完成,那么缓存未命中可能会比实际数学占用更多时间。

    1. 您可以使用例如 _mm_prefetch 或 __builtin_prefetch 预取数据(取决于您的编译器/平台)。
    2. 检查昂贵的函数是否存在输入和输出之间的别名;这些可能会导致额外的内存读/写。
    3. 考虑以不同的方式存储数据 - 如果流体求解器独立于 y 坐标求解 x 坐标,则将它们存储在不同的数组中可能对缓存更友好。如果它们一起解决,请考虑交错(例如 xyx y...)
  2. 展开- 您应该能够通过展开内部循环来获得性能优势。目标并不是(如许多人认为的那样)减少循环终止检查的数量。主要好处是允许独立指令交错,以隐藏指令延迟。这里有一个题为“VMX 优化:提升一个级别”的演示,可能会有所帮助;它主要关注 Xbox360 上的 Altivec 指令,但一些展开建议也可能对 SSE 有帮助。

正如其他人提到的,个人资料,个人资料,个人资料。然后让我们知道什么仍然很慢:)

PS - 在您的其他帖子中我说服您在矩阵求解器中使用 SOR 而不是 Gauss-Seidel。现在我想了一下,您不使用三对角解算器是否有原因?