问题 我应该优化多少?


关于编译器(GCC)所做的优化,标准做法是什么?每个选项(-O,-O1,-O2,-O3,-Os,-s,-fexpensive-optimizations)的作用有何不同,我如何确定最佳选项?


3671
2018-06-07 01:24


起源

stackoverflow.com/questions/19689014/... || stackoverflow.com/questions/11546075/... - Ciro Santilli 新疆改造中心 六四事件 法轮功


答案:


通常-O2是一个很好的优化级别,首先尝试。

但是,如果您希望获得最佳结果,则最终会尝试许多优化级别,因为您无法预先知道哪个级别最适合您的应用。

另请注意,优化结果应随每个CPU而变化(在某些CPU上,针对大小进行优化可能实际上产生比优化速度更好的速度)。

仅供将来参考,以下是每个级别的简要说明(您可以在文档中找到完整的说明 http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html):

-O(与-O1相同): 使用-O,编译器会尝试减少代码大小和执行时间,而不执行任何需要大量编译时间的优化。

-O2:优化甚至更多。 GCC几乎执行所有支持的优化,不涉及空速 - 权衡。与-O相比,此选项增加了编译时间和生成代码的性能。

-O3:优化更多。 -O3打开-O2指定的所有优化,并打开-finline-functions,-funswitch-loops,-fpredictive-commoning,-fgcse-after-reload,-ftree-vectorize,-ftree-partial-pre和 - fipa-cp-clone选项。

-Os:优化尺寸。 -Os启用所有通常不会增加代码大小的-O2优化。它还执行旨在减少代码大小的进一步优化。

-Ofast:忽视严格的标准合规性。 -Ofast启用所有-O3优化。它还支持对所有符合标准的程序无效的优化。它打开-ffast-math和Fortran特定的-fno-protect-parens和-fstack-arrays。 如果使用多个-O选项(包含或不包含级别编号),则最后一个选项是有效的选项。


8
2018-06-07 01:49



谢谢,特别是对于那个链接。很有帮助。


Linux内核的 Makefile 提供两者 -O2 和 -Os。任何一个都适合缺乏进一步的细节。

-Os 优化小型存储。由于CPU现在明显快于主内存,因此即使在大型机器上也可以优化小型存储 - 任何等待从主内存填充缓存的时间都是 浪费时间。因此,通过编译空间效率并且执行时间可能会充分利用指令缓存  提高。

-O2 运行所有“通常的优化”,并且所选择的优化将是安全的。 (我听说过一些 -O3 优化并不总是安全的,但这可能是因为Linux内核以一些常见应用程序不常见的约束运行。)

最好 答案当然是用多级优化来编译你的软件;时间编译软件所需的时间以及软件运行代表性基准测试所需的时间。测量所有内存的使用量。

然后选择编译速度,运行时速度和运行时内存使用的“最佳”组合。您可能想要最快的编译,或者您可能想要最快的运行时间,或者您可能尝试从虚拟主机提供商处获得较少的内存以节省资金。

选择它可能是公平的 -O2 没有做任何测量。


2
2018-06-07 01:36