为gcc启用优化的简便方法是将-0#
添加到编译器选项中。很有可能说-O3
。但是我知道-O3
包括非保存的优化,因为一旦包含此选项,数值计算的结果可能会有所不同。如果算法稳定,结果的微小变化可能是微不足道的。另一方面,精度可能是某些数学运算的问题,因此数学优化会产生重大影响。
我发现在调试过程中考虑编译器相关问题是不方便的。即我不想知道代码中的微小变化是否会导致强烈不同的行为,因为编译器在内部更改了它的优化。
如果我想在我的代码中使用确定性(因此可控制)行为,可以安全添加哪些选项?哪些几乎是安全的,也就是说,与性能优势相比,哪些选项仅引起轻微的不确定性?
我想到了像-finline -finline-limit=2000
这样的选项,即使它们很长也会内联。
答案 0 :(得分:7)
-O3
包含数字上不安全的优化是不正确的。根据{{3}},与-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__
被定义。除
-O
之外的任何-Ofast
选项都未启用此选项,因为它 可能导致依赖于精确的程序的输出不正确 数学函数的IEEE或ISO规则/规范的实现。 但是,它可能会为不需要的程序生成更快的代码 这些规范的保证。
换句话说,-O
,-O2
和-O3
都适用于数字编程。