O2和O3优化的FP代码之间存在截然不同的行为

时间:2016-08-17 19:46:02

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

我正在研究一些浮点数字代码,让我感到沮丧的是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能做什么样的优化才能真正为浮点计算做出巨大贡献呢?

1 个答案:

答案 0 :(得分:2)

来自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。