/Ox 和 /O2 编译器选项有啥区别?

Posted

技术标签:

【中文标题】/Ox 和 /O2 编译器选项有啥区别?【英文标题】:What is the difference between the /Ox and /O2 compiler options?/Ox 和 /O2 编译器选项有什么区别? 【发布时间】:2011-07-01 02:30:11 【问题描述】:

Microsoft 的 C++ 编译器(cl.exe,包含在 Visual Studio 中)提供 several optimization switches。它们中的大多数之间的区别似乎不言自明,但我不清楚/O2(优化代码以获得最大速度)和/Ox(选择“完全优化”)之间的区别。

我已尝试阅读 documentation 中的 /Ox 选项,似乎确认此开关还可以优化最大速度,而不是大小:

/Ox 编译器选项生成的代码有利于执行速度而不是更小的代码。

但特别是“备注”部分下的以下声明引起了我的注意:

通常,指定 /O2(最大化速度)而不是 /Ox

所以我的问题是,为什么人们通常更喜欢 /O2 而不是 /Ox 后一种选项是否启用了已知会导致无法预料的错误或其他意外行为的特定优化?仅仅是获得的优化量不值得额外的编译时间吗?或者这只是一个完全没有意义的“建议”,因为/O2 是 VS 中的 默认 选项?

【问题讨论】:

【参考方案1】:

我找到了here:

Ox 和 O2 几乎相同。他们 不同之处仅在于 O2 也 抛出 GF 和 Gy。几乎没有 避免扔这两个的原因 开关。

【讨论】:

干得好!我想我自己搜索的时间不够长。有趣的是,文档显示/Ox/O2 的优化级别更高。似乎这两者都至少会提供理论上的性能提升。 显然是这样。似乎使用 /OPT:REF 链接器选项和 /Gy 将有助于从最终 exe 中删除未引用的函数。不过,我不太确定 /GF 有多大用处。 /GF 很棒——它将所有相同的字符串文字汇集在一个只读内存区域中。因此,如果您在多个代码区域中有一些文字,那么您在可执行文件中只会有一次,这会减小图像大小。如果你的代码试图修改它,你会得到访问冲突,它可以保护你免受愚蠢的错误。 值得注意的是,据 Stephan T Lavavej(MS VC++ 的 STL 负责人)Microsoft's compiler backend team considers /Ox "an evil switch from beyond time" 并敦促大家使用 /O2 而不是 /Ox。【参考方案2】:

Asha's answer 引用了一篇关于 Visual Studio 2005 的博文,并且已经过时了。

最新版本的文档可在此处获得:

/Ox: https://msdn.microsoft.com/en-us/library/59a3b321.aspx /O2: https://msdn.microsoft.com/en-us/library/8f8h5cxt.aspx

根据那些:

/Ox/Og /Oi /Ot /Oy /Ob2

/O2 → 相同,但进一步添加/Gs /GF /Gy

/GFeliminates duplicate strings /Gy function level linking

您可能还对/GS- 感兴趣,它会关闭堆栈的安全检查,这可能会对性能造成重大影响(请参阅MS docs for /GS)。

您应该一如既往地对您的特定应用程序进行基准测试。

【讨论】:

写。你的外卖,那 /O2 可能暗示 /Gs0 ...看我的“怀疑”:***.com/questions/42342931/… /O2 在最新版本的 Visual Studio 中似乎没有暗示 /Gs(即 /Gs0):docs.microsoft.com/en-us/cpp/build/reference/…

以上是关于/Ox 和 /O2 编译器选项有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

Sencha Cmd 的“bundle”和“includeInBundle”选项有啥区别

“提供的文件”和“编译”有啥区别

GCC编译选项 -OX[转]

五大学科竞赛-o2 -lm编译选项

gcc 和VC++有啥区别呢,VC++编译时用的编译器 相当于gcc的是啥东西

O2优化的实质