【问题标题】:wildly different behaviour between O2 and O3 optimized FP code [closed]O2 和 O3 优化的 FP 代码之间的行为截然不同 [关闭]
【发布时间】:2016-12-24 14:38:05
【问题描述】:

我正在处理一些浮点数字代码,让我感到沮丧的是,O3 优化(GCC 4.8.3)代码的行为与 O2 情况(稳定的情况)产生了非常不同的结果,并且它结束了正如预期的那样,出现了数字灾难。

我查看了可能相关的this thread,但那里的答案并不能解决我的问题。我知道 O3 除了 O2 之外所做的主要是关于内联和循环展开。而且我很确定原因是由于浮点计算部分,因为在我明确使用 O2 优化该部分后,结果看起来很好。

#pragma GCC push_options
#pragma GCC optimize ("O2")

FP computation code (double precision)

#pragma GCC pop_options 

所以我的问题是,O3 所做的哪种优化真的可以对浮点计算产生巨大的影响?

【问题讨论】:

  • 它利用了未定义的行为?有更多细节吗?
  • 如果-fno-fast-math 没有解决问题,请发布受影响的代码示例。 (我不认为 -O3 会打开-ffast-math,但我可能错了。-ffast-math 是一种委婉说法;它可以实现广泛的不正确优化在浮点代码上。)
  • @zwol 但这不符合 IEEE-754 对吗?
  • 另外,如果您的代码使用 32 位 x86,请尝试 -mfpmath=sse。 (这是 x86-64 的默认设置。)
  • 发布您的代码。 -O3 包含不安全的数学优化。 -Ofast 会。

标签: c++ c gcc optimization floating-point


【解决方案1】:

来自GCC manual

-O3

进一步优化。 -O3 打开 -O2 指定的所有优化,同时打开 -finline-functions、-funswitch-loops、-fpredictive-commoning、-fgcse-after-reload、-ftree-vectorize、-fvect-cost-model、- ftree-partial-pre 和 -fipa-cp-clone 选项。

这些优化都不是特别不安全的。我看到的唯一可以改变结果的优化是-ftree-vectorize。在某些情况下,与 FPU 指令相比,使用向量指令可以改变结果。例如,FPU 默认使用 80 位内部精度进行双精度运算,而矢量 SIMD 指令使用 64 位。此外,一些数学函数(如sqrt)的实现可能会有所不同。

如果您发布您的代码、准确的编译器标志和有关您的硬件的信息(您的 CPU 有哪些 SIMD 指令),您将有更好的机会获得帮助。

您也可以直接比较这两种情况下生成的汇编代码。

PS。但根据我的经验,最可能的原因是程序中未定义的行为。通常,未初始​​化的变量、除以零等。确保编译时具有高警告级别 (-Wall -Wextra -Wpedantic),并使用 UB Sanitizer。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-06
    • 1970-01-01
    • 2021-11-17
    • 1970-01-01
    • 2015-12-25
    • 2018-04-14
    • 1970-01-01
    • 2021-08-28
    相关资源
    最近更新 更多