Visual Studio 2013 优化标志 (/O2 vs /Ox)

8

我一直在阅读有关各种优化标志的MSDN页面

我们目前将大多数项目设置为/O2,它针对“最大化速度”进行了优化。

我的困惑是这到底意味着什么。以下哪些陈述更接近于有关/O2标志的真相?

  1. 为速度和大小都优化代码,但如果存在争用,则优先为速度进行优化
  2. 仅为速度优化代码,不为大小进行优化。

我认为我们应该使用/Ox标志,但那是在我认为选项2为真时提出的。

基本上有人告诉我“除非有确凿的证据表明我们需要这样做”,否则我们不会从/O2切换到/Ox

所以我的问题是/O2是否仍然执行内存优化?例如返回值优化,复制省略等。从/O2切换到/Ox会给我们带来什么好处?


/O2页面明确提到了复制省略。而/Ox页面则表示:“一般情况下,请使用/O2(最大化速度)代替/Ox,使用/O1(最小化大小)代替/Oxs。” - Angew is no longer proud of SO
1
返回值优化、拷贝省略等主要是为了速度优化。这是我想说的。 - Angew is no longer proud of SO
通常情况下,应该使用 /O2(最大化速度)而不是 /Ox 来指定。 - NathanOliver
为什么不直接测量这些标志对你的软件产生了什么影响呢? - MikeMB
3个回答

9
正如Arkanosis所正确指出的,从/O2 到 /Ox,会禁用 /Gs, /GF, /Gy。问题是这些标志中哪个可能会提高执行速度?
/Gs与/Gs0相同,可能对性能产生负面影响。请参阅下面MSDN上的说明。
激活了每个需要存储本地变量的函数调用的堆栈探测。这可能对性能产生负面影响。
/GF消除重复的字符串(常量)-称为字符串池化。这将减少代码大小。较低的代码可能会产生更少的指令缓存未命中,但我怀疑这种效果在大多数代码中都不可观测。
/Gy标志允许将单个函数打包到COMDAT结构中。这些可以用作解决避免由于同一符号的多个定义而导致的编译时错误的解决方法。MSDN文档指出,这只会影响构建时间,而不会影响执行时间。他们通常建议使用它。
结论:
/Ox禁用了/Gs、/GF和/Gy。在某些情况下,这些选项会损害性能,并且与/O2相比,几乎从不提高执行速度。当然,它们具有好处,但与速度无关。

单独使用/Gy并不能提高运行时性能,但是链接器选项/OPT:REF可能会有所帮助(它确实可以减小文件大小,特别是当你链接静态库时),而且它需要/Gy。我从未见过有人争论字符串池对代码大小的减少是否有益。毫无疑问,合并重复字符串不会造成任何伤害 - Cody Gray
2
这部分内容有点令人困惑。你的意思是“它们几乎从不提高执行速度”吗? - Marc.2377

6
  • /02/Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy相同。
  • /Ox/Og /Oi /Ot /Oy /Ob2相同。

因此,从/O2切换到/Ox意味着:

  • 没有/Gs(没有控制堆栈探测)
  • 没有/GF(没有字符串池化)
  • 没有/Gy(没有函数级联)

0
所以我的问题是/O2是否仍然执行内存优化?
这取决于您对内存优化的理解。
/O1保证根据二进制大小优化代码。
在大多数情况下,创建最小的代码。
/O2主要旨在优化代码以获得更快的速度。
在大多数情况下,创建最快的代码(发布版本的默认设置)。
当编译器进行循环展开、代码重排序和代码内联时,/O2与/O1正交(不受限制)。
现在考虑/Ox,它生成有利于执行速度而不是较小大小的代码,因此/Ox不包括/Os(偏爱小型代码),通过指示编译器优先考虑大小而不是速度来最小化EXE和DLL的大小。

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