我从各种各样的消息来源(虽然大部分是我的一位同事)听说的,-O3以g ++的优化级别进行编译在某种程度上是“危险的”,除非被证明是必要的,否则通常应该避免编译。
这是真的吗?如果是这样,为什么?我应该坚持-O2吗?
在gcc的早期(2.8等)和egcs时代,redhat 2.96 -O3有时是相当多的错误。但这是十年前的事了,-O3与其他级别的优化(在儿童车中)没有太大不同。
但是,由于确实更严格地依赖语言的规则,特别是一些极端情况,它确实倾向于揭示人们依赖未定义行为的情况。
作为个人说明,我使用-O3在金融领域运行生产软件已有很多年了,并且还没有遇到过如果我使用-O2就不会出现的错误。
根据大众需求,这里有一个补充:
-O3尤其是诸如-funroll-loops之类的其他标志(未由-O3启用)有时会导致生成更多机器代码。在某些情况下(例如,在具有非常小的L1指令高速缓存的CPU上),这可能会导致速度变慢,这是因为某些内部循环的所有代码现在不再适合L1I。通常,gcc会尽力避免不生成太多代码,但是由于它通常会优化一般情况,因此可能会发生这种情况。-O3中通常不包括特别容易发生这种情况的选项(例如循环展开),并在手册页中进行了相应标记。因此,通常最好使用-O3来生成快速代码,并且仅在适当的时候(例如,当探查器指示L1I未命中时)回退到-O2或-Os(尝试对代码大小进行优化)。
如果您想将优化工作发挥到极致,则可以通过–param调整与某些优化相关的成本。另外请注意,gcc现在可以将属性放在仅控制这些功能的优化设置的功能上,因此,当您发现一个功能中的-O3有问题(或想尝试该功能的特殊标志)时,您无需使用O2编译整个文件甚至整个项目。
在使用-Ofast时,似乎必须小心,它指出:
-Ofast启用所有-O3优化。它还启用了并非对所有符合标准的程序都有效的优化。
这使我得出结论,-O3旨在完全符合标准。