当前位置: 首页 > 知识库问答 >
问题:

GCC:O3和-Os之间的差异

熊俊人
2023-03-14

我非常熟悉GCC-O3标志,但是它与-Os有什么不同,在什么情况下我们应该更喜欢一个而不是另一个?

共有3个答案

隆兴修
2023-03-14

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

-O3
优化更多。-O3打开-O2指定的所有优化,并打开-finline-函数、-funSwitch-loops、-f预测-通信、-fgcse-post-reload、-ftree-love-vectorize、-ftree-slp-vectorize、-fvect成本模型、-ftree-part al-preops和-fipa-cp-clone选项。

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

-操作系统
针对大小进行优化-Os支持通常不会增加代码大小的所有O2优化。它还执行进一步优化,以减少代码大小
-操作系统禁用以下优化标志:

< code >-faign-functions < code >-faign-jumps < code >-faign-loops < code >-faign-labels < code >-f order-blocks < code >-f order-blocks-and-partition < code >-fprefetch-loop-arrays

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

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

袁博
2023-03-14

建议看GCC文档。-O3用于获得快速运行的代码(即使以一些代码膨胀为代价),而< code>-Os用于优化生成代码的大小。

还有许多其他(模糊的)GCC优化标志(例如< code>-fgcse-sm),其中许多甚至在< code>-O3处都没有启用。

除了例如< code>-O3或< code>-Os之外,您可能还对在编译时和链接时使用-flto(用于链接时优化)感兴趣。然后也看这个回答。

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

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

您甚至可以编写自己的优化通行证,特定于您自己的特定库和API,也许可以使用MELT插件。

正如CmdrMoozy回答的那样,您可能更喜欢使用-O2而不是-O3(但请注意,最近的GCC版本已经改进了很多他们的-O3,因此Gentoo引用-推荐反对-O3并支持-O2变得不那么相关。)。

此外,正如这篇SlashDot ed堆叠论文(作者:Xi Wang、Nickolai Zeldovich、M.Frans Kaashoek和Armando Solar Lezama)所显示的那样,许多程序并不完全符合C标准,当完成一些有效的优化时,它们并不满意(并且行为不正确)。未定义的行为是一个棘手的问题。

顺便说一句,请注意,使用< code>-O3通常会使您的编译时间更长,并且通常(但不总是)会比< code>-O2甚至< code>-O1带来最多几个百分点的性能提升....(使用< code>-flto,情况会更糟)。这也是我很少用的原因。

羊光辉
2023-03-14

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

-O3会尽力优化代码以提高性能。它包括了所有的优化——O2包括的,还有更多。

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

请注意,我故意对我的描述有点模糊-阅读GCC留档以更深入地讨论为任一优化级别启用了哪些标志。

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

我想我也会从Gentoo Linux Wiki链接这篇文章,它讨论了优化标志,因为它们与构建操作系统的软件包有关。显然,并非所有这些都是适用的,但它仍然包含一些有趣的信息 - 例如:

使用 -O3 进行编译并不能保证提高性能,事实上,在许多情况下,由于二进制文件较大和内存使用量增加,系统速度会变慢。-O3也被称为破坏几个包。因此,不建议使用 -O3。

根据那篇文章,在大多数情况下,-O2“与”-O3一样好”,并且在可执行输出中断的情况下使用起来更安全。

 类似资料:
  • 问题内容: 很快就有两个相等运算符:double equals( )和Triple equals( ),两者之间有什么区别? 问题答案: 简而言之: 操作员检查其实例值是否相等, 操作员检查引用是否指向同一实例, 长答案: 类是引用类型,可能有多个常量和变量在幕后引用类的同一单个实例。类引用保留在运行时堆栈(RTS)中,其实例保留在内存的堆区域中。当您控制平等时, 这意味着它们的实例是否彼此相等。

  • 我编写了一个简单的脚本,它接受任意数量的参数来演示< code>$@和< code>$*之间的区别: 在我做的 CLI 上 这就是打印出来的 因为它们是相同的,这是否意味着等于?还是我遗漏了一点?

  • 问题内容: package main 该代码可以很好地工作。但是,如果按如下所示更改方法,则会导致死循环。区别在于将替换为。为什么? 问题答案: 因为程序包检查要打印的值是否具有方法(或换句话说:是否实现接口),如果是,则将调用它以获取值的表示形式。 软件包doc中对此进行了说明: […]如果操作数实现String()字符串方法,则将调用该方法将对象转换为字符串,然后根据动词的要求对其进行格式化(

  • 我正在通过做微控制器项目来自学C++。我当前的项目是使用一对或Adafruit羽毛分组无线电。无线电数据包的库函数需要一个C样式的字符串(我相信),我理解它是一个char的数组。 我已经设置了一个枚举来反映接收方的各种操作,并希望将该状态发送回发送方。所以我想把枚举变成char的数组。 在搜索将枚举转换为char数组的方法时,最简单的方法(对我来说)是将枚举变量传递给带有switch语句的函数,该

  • 我是Hadoop的新手。我正在浏览专业Hadoop解决方案的书,以获得一些关于Hadoop和生态系统的知识。我想澄清HDFS和HBase之间的主要区别是什么。我理解的方式就像两者都是存储系统。它们的区别只是在访问数据方面。HBase通过非关系型数据库访问数据,HDFS使用计算框架(MapReduce)处理数据。如果是这种情况,为什么我们不能只有一个存储HDFS或HBase。根据需求,他们将插入和插

  • 有人能解释一下 和 我不知道确切的意思。