如果函数内联过于激进会发生什么?

时间:2011-02-14 06:17:54

标签: c++ performance visual-c++ compiler-construction inline

每当我在C ++中阅读inline关键字时,都有一个很长的解释,即编译器会进行“速度与代码量”分析,然后决定是否在每个特定情况下内联函数调用。

现在Visual C ++ 9有一个__forceinline keyword,它似乎使编译器内联调用函数,除非这样的内联是绝对不可能的(比如调用是虚拟的)。

假设我查看了一些项目而没有理解其中的内容,并确定自己三分之一的函数足够小并且适合内联并使用__forceinline标记它们并且编译器会内联它们并且现在可执行文件具有说得大一百倍。

真的重要吗?如果功能过于激进并且可执行文件大一百倍,我应该期待什么效果呢?

6 个答案:

答案 0 :(得分:5)

主要影响将是缓存。内联违背了地方的原则; CPU必须更频繁地从主存储器中获取指令。因此,使代码更快的目的实际上可能会使代码变慢。

答案 1 :(得分:4)

其他人已经提到了对缓存的影响。还有另一个罚款。现代CPU非常快,但需要付出代价。他们有深入的指令流程正在处理中。为了在存在条件分支的情况下保持这些管道填充,快速CPU使用分支预测。它们记录分支的使用频率,并用它来预测将来是否会采取分支。

显然,这段历史需要记忆,它是一张固定大小的表格。它仅包含有限数量的分支指令。通过将指令数量增加百倍,您还可以增加分支数量。这意味着具有预测的分支数量急剧减少。此外,对于预测表中存在的分支,可用的数据较少。

答案 2 :(得分:3)

它会加载并运行得更慢,并且可能会耗尽虚拟地址空间(100倍大的非常可怕)。

答案 3 :(得分:3)

拥有更大的可执行文件是它自己的惩罚:

1)存储程序需要更多内存,这在某些系统上比其他系统更重要(例如手机内存非常有限)

2)拥有更大的程序需要更长的时间才能加载到内存中

3)在执行期间,您可能会有更多缓存未命中(您尝试分支到程序中不在缓存中的部分),因为您的程序分布在更多空间中。这会减慢您的计划。

答案 4 :(得分:2)

您的程序中较少的程序将适用于CPU缓存,磁盘缓存等,因此当CPU处于空闲状态等待该代码可用时,将浪费更多时间。它真的很简单。

啊 - 我没看过是谁发布了这个问题 - 犀利的嘿? :-) - 你显然不会从上面的答案中学到任何东西。但是,这就是它的全部 - 它只是一种统计平衡行为,与其他编译器供应商相比,编译器编写者基于客户压力无疑会形成默认值来解释更大的可执行文件大小和更慢的执行速度。

有趣的是,如果注明日期讲座,请注意:http://www.cs.utexas.edu/users/djimenez/utsa/cs3343/lecture15.html

答案 5 :(得分:1)

这有点复杂,我想你应该看看这个C++ faq lite about inline

它解释说没有简单的解决方案,并且有很多事情需要考虑(但无论如何都归结为良好的直觉!)