/Ox和/O2编译选项有什么区别?

82

Microsoft的C++编译器(cl.exe,包含在Visual Studio中)提供了多种优化开关。大多数开关之间的区别似乎是不言自明的,但我不清楚/O2(针对最大速度优化代码)和/Ox(选择“完整优化”)之间有何区别。

我尝试阅读有关/Ox选项的文档,似乎证实了该开关还启用了针对最大速度的优化而非大小:

/Ox编译器选项生成更偏重于执行速度而非大小的代码。

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

一般情况下,请使用/O2(最大化速度)而不是/Ox

所以我的问题是,为什么一般情况下应该青睐/O2而不是/Ox后者选项是否启用了一种已知会导致意外错误或其他不可预见行为的特定优化?只是因为获得的优化量不值得额外的编译时间吗?还是这只是一个毫无意义的“建议”,因为在VS中/O2是默认选项?

2个回答

59

我在这里找到了:此处:

Ox和O2几乎是相同的。它们唯一的区别在于,O2还会抛出GFGy。几乎没有理由避免抛出这两个开关。


干得漂亮!我想我自己可能没搜索够长的时间。有趣的是,文档让人觉得 /Ox/O2 更高级一些。看起来这两个都至少提供了理论上的性能提升。 - Cody Gray
看起来是这样的。使用 /OPT:REF 链接器选项以及 /Gy 可以帮助从最终的 exe 中删除未被引用的函数。但我不是太确定 /GF 有多有用。 - Asha
16
/GF很棒 - 它会将所有相同的字符串常量汇总到只读内存区域。因此,如果您在代码的多个区域中有某些常量,那么可执行文件中只会有一个,这可以减小映像大小。如果您的代码试图修改它,您将会得到访问冲突的错误提示,从而保护您免受愚蠢错误的影响。 - sharptooth
8
值得注意的是,根据斯蒂芬·T·拉瓦维奇(MS VC ++的STL主管)所说,微软的编译器后端团队认为/Ox是“来自时空以外的邪恶开关”,并敦促每个人使用/O2而不是/Ox。 - Chris Kline

56

Asha's answer引用了一篇关于Visual Studio 2005的博客文章,已经有些过时。

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

根据这些信息,可以得到:

您可能还对/GS-感兴趣,它关闭了有关堆栈的安全检查,这可能会导致性能下降(请参阅 MS文档中的/GS)。

无论如何,您都应该针对特定的应用程序进行基准测试。


关于你的疑问,/O2 可能意味着 /Gs0 ... 请参考我的“疑虑”:http://stackoverflow.com/questions/42342931/does-msvc-o2-imply-gs0-or-gs4096 - Martin Ba
1
在最新版本的Visual Studio中,/O2似乎不意味着/Gs(即/Gs0)。参考链接:https://learn.microsoft.com/en-us/cpp/build/reference/o1-o2-minimize-size-maximize-speed - Chris Kline

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接