当可执行文件大小没有严格限制时,为什么在 Visual C++ 9 中更喜欢 /Ob1 而不是 /Ob2?

问题描述 投票:0回答:5

Visual C++ 具有

/Ob
控制函数内联的编译器选项。使用
/Ob1
时,仅内联标记为
inline
__inline
或在类声明中定义的函数,而使用
/Ob2
时,编译器认为合适的所有函数都会内联。

我可以想象一些项目对图像大小有非常严格的限制,使用

/Ob1
而不是
/Ob2
。令人惊讶的是,我们发现一个项目对图像大小没有严格的限制,但却使用了
/Ob1
,而且我们找不到任何这样做的原因。

为什么对可执行文件大小没有严格限制的项目会更喜欢

/Ob1
而不是
/Ob2

c++ visual-c++ inline compiler-optimization
5个回答
3
投票

因为更多的内联会导致代码变大,从而导致缓存利用率降低。由于现代 CPU 会进行积极的分支预测,因此跳入/跳出函数的成本并不一定很高。

缓存的大小有限,因此通过内联代码强制 CPU 放弃缓存中可能存在的其他内容,从而增加未命中次数,从而导致 CPU 停顿。


3
投票

/Ob1
的选择可能根本就不是选择,而是一种疏忽。现在看到
/Ob1
标志的主要原因是因为它是 CMake 对于 RelWithDebInfo 构建的默认设置。这可能会导致 RelWithDebInfo 和 Release 版本之间存在重大性能差异。我认为这是 CMake 中的一个陷阱,应该将 RelWithDebInfo 更改为默认使用
/Ob2


1
投票

就速度而言,没有真正的原因。内联有一定的权衡,但编译器的启发式几乎肯定比用户更聪明。


1
投票

我在 64 位发布版本中遇到了 /Ob2 的编译器错误。 使用 /Ob1 可以使问题消失。 项目的开发者可能也遇到过相同或类似的问题。


0
投票
  1. 第一种情况下编译时间可能会稍快一些。
  2. 编译器可能并不总是对使用哪些函数做出最佳决定 排队。由于缓存溢出等副作用,内联更多内容以使单个函数更快,总体上可能会使整个程序运行更慢。
© www.soinside.com 2019 - 2024. All rights reserved.