GCC:-O3和-Os之间的差异

时间:2013-10-30 16:50:44

标签: c++ c gcc compiler-construction g++

我对GCC -O3标志非常熟悉,但是它与-Os有什么不同,在哪种情况下我们应该比其他人更喜欢?

5 个答案:

答案 0 :(得分:24)

GCC documentation非常明确地描述了这些选项的作用。

-O3尝试极大地优化代码以提高性能。它包括所有优化--O2包括,以及更多。

另一方面,-Os指示GCC“优化规模”。它启用所有-O2优化,它们不会增加可执行文件的大小,然后它还会切换一些优化标志以进一步减少可执行文件的大小。

请注意,我的描述有点模糊不清 - 请阅读GCC文档,以便更深入地讨论哪些标志都为优化级别启用了。

我相信-O *优化级别就是 - 优化的互斥,独特的级别。混合它们并没有多大意义,因为两个级别将启用或省略另一个有意遗漏或启用的标志(分别)。如果你想混合和匹配(你可能实际上不想这样做,除非你有一个非常好的理由想要一组特定的标志),你最好阅读文档并混合和匹配每个级别的标志手动启用。

我想我也会链接来自Gentoo Linux Wiki的this article,它讨论了与构建操作系统软件包有关的优化标志。显然并非所有这些都适用,但它仍然包含一些有趣的信息 - 一个:

  

使用-O3进行编译并不是提高性能的有保证的方法,实际上在很多情况下由于更大的二进制文件和更大的内存使用量而导致系统速度变慢。 -O3也可以打破几个包。因此,不建议使用-O3。

根据那篇文章,-O2在大多数情况下“和-O3一样好”,并且对于破碎的可执行输出更安全。

答案 1 :(得分:6)

我建议阅读GCC文档。 -O3用于获取快速运行的代码(即使以某些代码膨胀为代价),而-Os正在针对生成的代码的大小进行优化。

还有大量其他(模糊的)GCC optimization flags(例如-fgcse-sm),其中许多甚至在-O3都没有启用。

您可能也会对-flto(对于链接时优化)感兴趣,此外还可以使用-O3-Os,无论是在编译时还是在链接时。然后另见this answer

最后,请注意使用最新版本的GCC(目前在2013年底为4.8),因为GCC正在显着改进其优化。

您可能还想使用-mtune=native(至少对于x86)。

您甚至可以编写自己的优化传递,特定于您自己的特定库和API,可能使用MELT插件。

作为CmdrMoozy answered您可能更喜欢使用-O2而不是-O3(但请注意,最近的GCC版本已经改进了很多-O3,所以 Gentoo citation -recommending -O3并赞成-O2变得不那么重要了。)。

此外,正如此SlashDot-ed Stack paper(来自Xi Wang,Nickolai Zeldovich,M。Frans Kaashoek和Armando Solar-Lezama)所示,许多节目并不完全符合C标准并且不满意(以及当某些有效优化完成时,表现不正确)。 Undefined behavior是一个棘手的主题。

BTW,请注意,使用-O3通常会使您的编译时间更长,并且经常(但并非总是)带来的性能最多比-O2甚至-O1高几个百分点。 ......(-flto)更糟糕。这就是 I 很少使用它的原因。

答案 2 :(得分:3)

这取决于。您需要优化速度或尺寸吗?

  

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

     

<强> -O0
  减少编译时间并使调试产生预期的结果。这是默认值。

     

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

     

-falign-functions -falign-jumps -falign-loops -falign-labels   -freorder-blocks -freorder-blocks-and-partition   -fprefetch-loop-arrays

     

http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

实际上, -O 是一长串独立优化的简写。如果您不知道自己需要什么,只需选择 -O3

答案 3 :(得分:0)

-O3优化速度,而-Os优化空间。这意味着-O3将为您提供快速可执行文件,但它可能相当大,并且-Os为您提供较小的可执行文件,但它可能会更慢。

空间和时间效率通常是一种权衡。更快的算法往往占用更多空间,其中就地算法(不增加空间使用的算法)往往效率较低。

通常现代计算机有足够的内存空间,因此-O3通常更可取。但是,如果您正在使用低ram(如小型设备)进行编程,则可能更喜欢-Os

答案 4 :(得分:-1)

这真的无法回答,一个简单的规则是在关键代码路径上使用优化速度,并在非关键代码路径上优化大小,例如加载,......

有些编译器可以在两个通道中为你决定它,第一个创建一个具有profiling支持的特殊可执行文件,你运行应用程序来收集数据,第二个编译能够根据什么是数据来决定最好。它允许去虚拟化,分支预测......