performance - 定点算术值得我费心吗?

标签 performance floating-point x86 fixed-point

我正在研究应该实时运行的流体动力学 Navier-Stokes 求解器。因此,性能很重要。

现在,我正在查看许多紧密循环,每个循环都占执行时间的很大一部分:没有单一的瓶颈。这些循环中的大多数执行一些浮点运算,但中间有很多分支。

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

我使用的大多数浮点值都有一个相当小的上限,接近零值的精度并不是很重要。所以我想到了:也许切换到定点算法可以加快速度?我知道唯一确定的方法就是衡量它,这可能需要几天时间,所以我想事先知道成功的几率。

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

最佳答案

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

您说编译器正在发出 SSE 指令,但听起来您并没有尝试编写矢量化的 SSE 代码。我不知道编译器通常在这方面有多好,但这是需要调查的。

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

  • 内存访问 - 如果您的所有计算都是在 SSE 中完成的,那么缓存未命中可能比实际数学花费更多的时间。
  • 您可以使用例如预取数据_mm_prefetch 或 __builtin_prefetch (取决于您的编译器/平台)。
  • 检查昂贵的函数是否存在输入和输出之间的混叠;这些会导致额外的内存读/写。
  • 考虑以不同的方式存储您的数据 - 如果您的 x 坐标的流体求解器求解器独立于 y 坐标,则将它们存储在不同的数组中可能对缓存更友好。如果它们一起解决,请考虑交错(例如 x y x y ...)
  • 展开 - 您应该能够从展开内部循环中获得性能优势。目标不是(正如许多人认为的那样)减少循环终止检查的次数。主要好处是允许独立指令交错,以隐藏指令延迟。有介绍here题为 VMX 优化:将其提升到一个可能会有所帮助的水平;它专注于 Xbox360 上的 Altivec 说明,但一些展开建议也可能对 SSE 有所帮助。

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

    PS - 在您的其他帖子之一 here ,我说服您在矩阵求解器中使用 SOR 而不是 Gauss-Seidel。现在我考虑一下,您是否有理由不使用三对角求解器?

    关于performance - 定点算术值得我费心吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2667397/

    相关文章:

    PHP:将列表插入数据库的有效方法

    types - IEEE 754 float 无法准确表示的第一个整数是哪一个?

    c - 在寄存器中存储无符号字符(x86 程序集)

    sql - 标准化数组下标,使它们从 1 开始

    java - Spring Data Mongodb 的性能问题

    javascript - JSPack 无法将 double 转换为字节

    haskell - 将 Haskell Word32/64 中的 IEEE 754 浮点与 Haskell Float/Double 相互转换

    linux - 映射 MMIO 区域回写不起作用

    assembly - 有没有办法获取寄存器的地址?

    c++ - 当明显不相关的代码被更改时,性能差异很大