在GCC中使用-O3有什么缺点吗?

Ric*_*lis 9 c c++ gcc

我已经在各种语言中担任了13年的软件工程师,尽管我现在正在进入C和后来的C++.当我正在学习C时,我正在使用GCC编译器来编译我的程序,我想知道是否有使用-O3或其他优化标志的问题.如果没有测试编译的代码,或者在交叉编译期间,我的软件可能会破坏我无法捕获的方式,我可能会无意中混淆了某个不同的平台.

在我盲目地打开这些选项之前,我想知道我能期待什么.此外,由于-Ofast打开了不符合标准的标志,我倾向于不使用它.在我的假设中,我是否正确--Ofast很可能会产生"副作用?"

在发布此问题之前,我已经浏览了https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html.

Sor*_*ren 10

唯一的缺点-O3应该是无法在调试器中遵循代码.

使用-Ofast会影响某些浮点运算导致舍入错误,但除非您运行特定的长浮点计算链,否则您不太可能注意到.

破坏的代码(带有错误指针的代码或具有未定义行为的语句)可能在不同的优化级别上表现不同 - 许多程序员的第一反应是责怪编译器 - 启用所有警告并修复它们通常会有所帮助.

  • @RickMacGillis`-Wall -Wextra -pedantic`是得心应手,而且也要记得手动指定语言标准(`-std = c11`或`-std = C++ 14`),或者这反而会给你GNU模式有一堆(有用的,但非标准的)扩展. (4认同)

Dao*_*Wen 7

重要的是要记住几乎所有编译器优化都是启发式的.换句话说,"optmization"只是试图使你的程序更"理想",但它可能会产生相反的效果.只是因为-O3它应该比它更好-O2,而且-O2应该更好-O1- 这并不意味着它实际上总是如何运作.

有时,-O3与使用-O2或生成的版本相比,启用"优化" 可能实际上会降低程序速度-O1.您应该尝试不同级别的优化,以查看哪种方法最适合您的特定代码.如果您真的想要对其进行微调,您甚至可以打开和关闭各个选项.

所以简而言之,使用起来可能会有缺点-O3.我个人观察到我写的很多内容-O2比使用的更好-O3- 但这确实是程序特定的.


仅供参考,这是另一个问题,问为什么-O2给出比-O3特定程序更好的结果:gcc优化标志-O3使代码慢于-O2


278*_*528 6

“我想知道我能期待什么”

我在嵌入式系统中使用 C++(主要是 vxWorks 上的 GCC)已有 20 多年了。我非常尊重编译器作者。


相信你的编译器:恕我直言,-O3 从未破坏过任何代码……但有时会揭示有趣的编码错误。


选择:团队必须选择是否发布您测试的内容,并测试您发布的内容”,无论选择 -O1 或 -O3。我合作过的团队始终致力于使用 -O3 进行发布和测试。


单步可能不合作:在个人实践水平上,当使用 -O3 代码时,我通常“放弃”gdb 单步。我更多地使用断点,并且编码选择略有不同,以使自动变量(堆栈数据)和类数据更加“可见”。(您可以让 gdb 命令 'p' 成为您不方便的朋友)。


单步是必要的:请注意,即使我们使用 -O3“测试和发布”,我们也几乎完全使用 -O1 代码进行调试。


调试是必要的:调试 -01 与测试和交付 -O3 之间的权衡是切换两个可执行文件所需的额外重新编译。-O1 中节省的用于探索、识别和修复代码错误的时间必须弥补 2 次重建(到 -01 并返回到 -O3)。


回归测试自动化:我想说-O3的系统测试(又名集成测试或回归测试)必须提高一个档次,但我无法真正描述它......也许我应该建议测试自动化的水平更高(每一项回归测试!)。但我不确定。回归测试的自动化水平可能更多地与团队规模相关,而不是与绩效水平相关。


“成功的”嵌入式系统有两件事。它满足要求。而且,我认为更重要的是,在所有人类可见行为中,它就像一个轻载的桌面。对于任何操作(按下按钮、断开电缆、测试设备引起的错误,甚至状态灯的微弱变化),结果都没有人类可察觉的延迟。-O3 有帮助。一个成功的系统是可以做的……我已经看到了。