【问题标题】:Secure gcc optimization options for numerics数字的安全 gcc 优化选项
【发布时间】:2012-11-11 05:01:19
【问题描述】:

哪些 gcc 编译器选项可以安全地用于数值编程?

启用 gcc 优化的简单方法是将-0# 添加到编译器选项中。很容易说-O3。但是我知道-O3 包含非保存优化,因为一旦包含此选项,数值计算的结果可能会有所不同。如果算法稳定,结果的微小变化可能是微不足道的。另一方面,精度可能是某些数学运算的问题,因此数学优化可能会产生重大影响。

我发现在调试过程中考虑编译器相关问题很不方便。 IE。我不想怀疑代码中的微小变化是否会导致截然不同的行为,因为编译器在内部改变了它的优化。

如果我希望代码中的行为具有确定性,因此可以安全添加哪些选项?哪些几乎是安全的,也就是说,与性能优势相比,哪些选项只引起很小的不确定性?

我想到了这样的选项:-finline -finline-limit=2000,即使它们很长,也会内联函数。

【问题讨论】:

  • 如果您的数值程序足够敏感以至于浮点关联性很重要,那么您可能应该重新检查正在使用的算法,而不是尝试使用编译器选项。
  • 我试图强调,独立于我无法直接影响的内部编译器优化获得相同的数值结果对我来说很重要。即使对于完全稳定的代码,大多数可以想象的数学优化如果到位,也会导致微小的差异。我不想要这种依赖,因为我想要设计和调试阶段的确定性行为,我不能排除算法的“不稳定性”。
  • 如果是这样,那么您真正需要的是strict-floating-point。即使是正常的优化级别也不是完全确定的,因为该标准允许将中间体提升到更高的精度。
  • 您应该知道浮点运算并不是唯一受优化器标志影响的运算。 -O0 可能会掩盖缺少的返回语句,并且许多其他事情也可能会发生变化,尤其是在您的代码不正确的情况下。

标签: c optimization gcc compiler-construction numeric


【解决方案1】:

-O3 包含数值上不安全的优化是不正确的。根据the manual-O3-O2 相比包括以下优化通道:

-finline-functions-funswitch-loops-fpredictive-commoning-fgcse-after-reload-ftree-vectorize-fipa-cp-clone

您可能指的是-ffast-math,默认使用-Ofast 打开,但没有使用-O3

-ffast-math 设置 -fno-math-errno-funsafe-math-optimizations-ffinite-math-only-fno-rounding-math-fno-signaling-nans-fcx-limited-range。此选项会导致定义预处理器宏 __FAST_MATH__

这个选项除了-Ofast之外的任何-O选项都没有打开,因为它 可能导致依赖于精确的程序的输出不正确 为数学函数执行 IEEE 或 ISO 规则/规范。 但是,它可能会为不需要的程序生成更快的代码 这些规范的保证。

换句话说,所有-O-O2-O3 都可以安全地进行数值编程。

【讨论】:

  • 我主要使用 intel 编译器已经有一段时间了(出于相关原因)。我记得 gcc 在我用于 numeric 的上一个版本中没有实现确定性行为,因为中间结果没有四舍五入到机器精度。根据上面 Mystical 的链接,如果没有快速数学,这不应该是这种情况,但它肯定是。
  • @highsciguy 这个问题确实提到了“gcc 编译器选项”,所以我假设是 gcc。
  • 我说的是 gcc(我考虑改回某些应用程序)。我只是想提一下,我没有使用最新版本的 gcc 的经验。
猜你喜欢
  • 2021-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多