为什么在 Visual C 中更喜欢 /Ob1 而不是 /Ob2? 9 当可执行文件大小没有严格限制时?
Visual C++ 功能 /Ob
< /a> 控制函数内联的编译器选项。对于 /Ob1
,只有标记为 inline
、__inline
或在类声明中定义的函数才会被内联,而对于 /Ob2
编译器认为合适的所有函数都是内联的。
我可以想象一些项目使用 /Ob1
而不是 /Ob2
对图像大小有非常严格的限制。令人惊讶的是,我们发现一个项目对图像大小没有严格的限制,但它使用的是 /Ob1
,而且我们找不到任何这样做的原因。
为什么对可执行文件大小没有严格限制的项目更喜欢 /Ob1
而不是 /Ob2
?
Visual C++ features /Ob
compiler option that controls function inlining. With /Ob1
only functions marked inline
, __inline
or defined within the class declaration are inlined, while with /Ob2
all functions the compiler considers suitable are inlined.
I can imagine some project that has very tight limitations on the image size using /Ob1
instead of /Ob2
. Surprisingly we found a project that has no tight limitations on image size yet it was using /Ob1
and we can't find any reasons why it does so.
Why would a project that has no tight limitations on executable size prefer /Ob1
over /Ob2
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
因为更多的内联会导致更大的代码,从而导致缓存利用率降低。由于现代 CPU 会进行积极的分支预测,因此跳入/跳出函数的成本并不一定很高。
不过,缓存的大小有限,因此通过内联代码强制 CPU 放弃缓存中可能存在的其他内容,从而增加未命中次数,从而导致 CPU 停顿。
Because more inlining leads to larger code, which leads to less efficient cache utilization. Since modern CPU:s do aggressive branch-prediction, jumps into/out of a function need not be very costly.
The cache is of limited size though, so by inlining code that forces the CPU to ditch other things that might have been in the cache, thus increasing the number of misses and thereby stalls the CPU has.
/Ob1
的选择可能根本不是一个选择,而是一个疏忽。现在看到标志/Ob1
的主要原因是它是 CMake 对于 RelWithDebInfo 构建的默认设置。这可能会导致 RelWithDebInfo 和 Release 版本之间出现重大性能差异。我认为这是 CMake 中的一个陷阱,应该将 RelWithDebInfo 更改为默认使用/Ob2
。The choice of
/Ob1
may not be a choice at all, but an oversight. A major cause of seeing the flag/Ob1
nowadays is because it is CMake's default for RelWithDebInfo builds. This can cause major performance differences between RelWithDebInfo and Release builds. I think this is a trap in CMake and RelWithDebInfo should be changed to use/Ob2
by default.就速度而言,没有真正的原因。内联有一定的权衡,但编译器的启发式几乎肯定比用户更聪明。
There is no real reason, in terms of speed. Inlining has certain tradeoffs, but the compiler's heuristic is almost certainly smarter about it than a user.
我在 64 位发布版本中遇到了 /Ob2 的编译器错误。使用 /Ob1 可以使问题消失。项目的开发者可能遇到过相同或类似的问题。
I've encountered a compiler bug with /Ob2 with 64-bit Release builds. Using /Ob1 makes the problem disappear. The developer of the project may have encountered the same or a similar problem.
排队。由于缓存溢出等副作用,内联更多内容以使单个函数更快,总体上可能会使整个程序运行更慢。
inline. Inlining more to make single functions faster, may in total make the entire program run slower, due to side effects like cache spill.