optimization - float 代码与 GCC 的一致行为

标签 optimization gcc floating-point

我做一些数值计算,在使用 GCC 时经常遇到浮点计算问题。对于我目前的目的,我不太关心结果的真实精度,但我想要这个公司属性:

无论 SAME 代码在我的程序中的何处,当它在 SAME 输入上运行时,我都希望它提供 SAME 输出。

我如何强制 GCC 这样做?具体来说,--fast-math 和不同的 -O 优化的行为是什么?

我听说 GCC 可能会尝试变得更聪明,有时会在寄存器中加载 float ,有时会直接从内存中读取它们,这可能会改变 float 的精度,从而导致不同的输出。我怎样才能避免这种情况?

再一次,我想要:

  • 我的计算要快
  • 我的计算是可靠的(即相同的输入 -> 相同的结果)
  • 我不太关心这个特定代码的精度,所以如果降低精度可以带来可靠性,我可以接受

谁能告诉我解决这个问题的方法是什么?

最佳答案

如果您的目标包括 x86 处理器,使用使 gcc 使用 SSE2 指令(而不是历史上基于堆栈的指令)的开关将使它们运行得更像其他处理器。

如果您的目标包括 PowerPC 处理器,使用开关使 gcc 使用 fmadd 指令(替换源代码中的乘法和加法)将让这些运行起来更像其他的。

不要使用--fast-math:这允许编译器走一些捷径,这会导致架构之间的差异。如果没有此选项,Gcc 更符合标准,因此可预测。

在您的应用程序中包含您自己的数学函数(expsin ...),而不是依赖于系统库中的数学函数,这只会有助于提高可预测性。

最后,即使编译器确实严格遵守标准(我这里指的是 C99),也可能存在一些差异,因为 C99 允许以比表达式类型所需的精度更高的精度计算中间结果。如果你真的希望程序总是给出相同的结果,写three-address code .或者,仅使用可用于所有计算的最大精度,如果您可以避免使用历史 x86 指令,则精度为 double。在任何情况下,不要使用低精度 float 来提高可预测性:根据标准中的上述条款,效果会适得其反。

关于optimization - float 代码与 GCC 的一致行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2340573/

相关文章:

python - 通过使列表等于一个切片或使用 del 来截断列表是否更快?

optimization - Levenberg-Marquardt 算法的局限性

c - 体系结构 x86_64 MAC GCC 的 undefined symbol

gcc - 如何在x86平台上使用gcc将内存范围声明为不可缓存?

java - Java 中的 0.0 和 -0.0 (IEEE 754)

mysql - 将前n行的ID从一个表复制到另一个表

optimization - 多类 Logistic 回归的学习曲线

c - 如何使用宏进行 undefined reference

floating-point - 理解 2^x 的浮点表示

floating-point - 逆向工程专有 float 编码