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