-O3(优化级别3)有什么问题?

问题描述:

我注意到在QT Creator发布版本的默认优化级别是-O2。我想知道:为什么不是-O3?我读过堆栈溢出它可能是危险的或“bug暴露”,但那些优化标志哪些被认为是更有风险而不是有用的,为什么?-O3(优化级别3)有什么问题?

优化级别3标志(上GCC):

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

它更像每一个使用O2,所以它是更好的测试。没有具体的事情,这导致O3代码编译为越野车。更像是大多数事情都是在O2上进行的,所以当使用O2优化时,你不太可能会得到错误。 O3不应该产生错误(假设编译器没有错误) – DawidPi

+2

@DawidPi,如果是这样的话,为什么O3不是每个人都使用的级别,如果它通常提供更好或相同的性能?我想我们会从这个问题中学到一些东西。如果没有人首先到达那里,我会对此进行一些研究。 – merlin2011

+1

http://*.com/questions/5637828/why-would-one-ever-want-to-compile-with-o2-instead-of-o3有一些关于它 – DawidPi

除了编译器错误,这可能是一个神话。这是-Ofast选项有风险,因为那个人甚至不保证符合标准的程序不会中断。

就像一个实际的例子,这里有一个快速搜索库,没有特定的顺序,在Android开源项目(AOSP)—内这可能是够“真正的生产代码库” —使用-O3的:

cblas,OpenSSH的,是libmpeg2,libavc,lvvm:MCJIT,JPEG,ZLIB,LZ4,正则表达式-RE2,libpng的,libutf,(多)

其他代码在AOSP简单地尝试优化大小(仍然是Android),所以它明确使用-Os。但是大部分代码仍然使用所有这些库,其性能比尺寸更大。还要注意,正确性可能是一个大问题,尤其是对于上面偶然提到的openssh之类的问题。

请记住,程序员总是倾向于对优化代码更加怀疑。如果您没有设置编写符合标准的代码,并深入研究未定义行为的领域,理论上不会阻止编译器在不同配置(如优化级别)之间生成不同结果。因此,当你主要在一个特定的级别(调试)上做你的工作时,你倾向于将它作为你的基本参考点,然后,当你切换时,很容易将责任归咎于优化器—,其中,尽可能它担心,可能会做很多事情来保持符合标准,不像我们自己的代码。

评价的良好连接的总结:-O2通常优于更高优化由于水平:

  • 较小生成码量(通常相当于因为对于分支预测处理器高速缓存的性能越好)
  • 更少的编译时间
  • 在您的代码中更容易暴露在更高优化级别中的错误。

优化器错误并非前所未闻,但大多数时候真正的原因是源代码中未定义的行为。另一方面,我记得一个15岁以上(商业)的编译器,它充斥着优化错误,并且在一个实例中甚至设法“修复”了一个错误的程序。

关于优化级别之间的速度差别:SunCC的文档读取的内容类似于“-O4通常比-O3更快,-O3通常比-O2更快,但有时-O2会击败所有其他的。”。根据我的经验,-O2往往更快,不仅仅是有时。

+0

但是当你谈论错误时,关卡之间有什么区别? GCC的文档中是否有这样的说法:“更有可能出现错误的优化进入更高的数字级别?” –

+0

@YamMarcovic当然不是。优化器错误(导致预期行为以外的错误)是编译器错误,应该修复而不管级别如何。具有未定义行为的源代码或'--fast-math' ...这些都没有编译器错误。 –