【问题标题】:Visual Studio 2013 optimization flags (/O2 vs /Ox) [duplicate]Visual Studio 2013 优化标志(/O2 vs /Ox)[重复]
【发布时间】:2015-06-20 10:19:54
【问题描述】:

我一直在尝试阅读 MSDN pages 上的各种优化标志。

我们目前将大部分项目设置为/O2,以优化“最大化速度”。

我的困惑是这到底意味着什么。关于/O2 标志,以下哪项陈述更接近正确?

  1. 针对速度和大小优化代码,但如果存在争用首选针对速度进行优化
  2. 优化代码速度,不优化大小。

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

我基本上被告知“我们不会从 /O2 更改为 /Ox,除非有人有确凿的证据表明我们需要这样做”。

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

【问题讨论】:

  • /O2 页面明确提到了复制省略。 /Ox 页面显示“通常,指定 /O2(最大化速度)而不是 /Ox,指定 /O1(最小化大小)而不是 /Oxs。”
  • 返回值优化、复制省略等主要是速度优化,我想说。
  • 来自 /Ox 上的链接“通常,指定 /O2(最大化速度)而不是 /Ox”
  • 你为什么不衡量这些标志对你的软件有什么影响?

标签: c++ performance optimization visual-studio-2013 compiler-optimization


【解决方案1】:

正如 Arkanosis 正确指出的那样,从 /O2 到 /Ox 时,您会禁用 /Gs、/GF、/Gy。问题是哪些标志可以提高执行速度?

/Gs/Gs0 相同,并且会对性能产生负面影响。请参阅下面 MSDN 上的说明。

为每个需要存储的函数调用激活堆栈探测器 对于局部变量。这可能会对性能产生负面影响

/GF 消除重复字符串(常量) - 称为 字符串池。这将减少代码大小。较低的代码可能会产生较少的指令缓存未命中数,但我怀疑这种影响在大多数代码上都可以观察到。

/Gy 标志允许将单个函数打包到 COMDAT 结构中。这些可以用作一种解决方法,以避免由于同一符号的多个定义而导致的编译时错误。 MSDN 文档指出,这只会影响构建时间,但不会影响执行时间。他们通常建议使用它。

结论:

/Ox 禁用 /Gs、/GF、/Gy。在某些情况下,与 /O2 相比,这些选项会损害性能并且几乎不会提高执行速度。当然它们有好处,但与速度无关。

【讨论】:

  • /Gy 本身并不能提高运行时性能,但 /OPT:REF 链接器选项可能会(它肯定会减小文件大小,尤其是在使用静态库链接时),并且它需要/Gy。我也从未见过有人争论字符串池减少代码大小是否有益。合并重复字符串当然没有危害
  • “而且几乎从来没有他们不提高执行速度” - 这部分有点令人困惑。您的意思是“而且它们几乎从不提高执行速度”?
【解决方案2】:
  • /02/Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy 相同
  • /Ox/Og /Oi /Ot /Oy /Ob2 相同

所以从/O2 切换到/Ox 意味着:

  • 没有/Gs(没有控件堆栈探测)
  • 没有/GF(没有字符串池)
  • 没有/Gy(没有函数级链接)

【讨论】:

    【解决方案3】:

    所以我的问题是 /O2 仍然执行内存优化吗?

    取决于内存优化的含义。

    /O1 保证根据二进制大小优化代码。

    在大多数情况下创建最小的代码。

    /O2 主要旨在优化代码以获得更快的速度。

    在大多数情况下创建最快的代码。 (默认设置 用于发布版本)

    当 /O2 与 /O1 正交时的情况(不限于)

    • 编译器进行循环展开,
    • 代码重新排序
    • 代码内联

    现在考虑 /Ox,它生成的代码有利于执行速度而不是较小的大小,因此 /Ox 不包含 /Os(支持小代码)通过指示编译器优先考虑大小而不是速度来最小化 EXE 和 DLL 的大小。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-28
      • 2011-08-25
      • 1970-01-01
      • 2015-05-06
      • 2011-06-27
      • 1970-01-01
      • 2015-02-12
      相关资源
      最近更新 更多