【问题标题】:Why can forced inline functions lead to bad performance? [duplicate]为什么强制内联函数会导致性能不佳? [复制]
【发布时间】:2015-01-14 17:28:48
【问题描述】:

如果我内联一个函数。 将复制函数调用主体,而不是对其发出 call()。 为什么会导致性能不佳?

编辑:那么由于大功能而导致缓存未命中怎么办? 那么为什么存在“只有最多 3 行的内联函数”的经验法则呢?

【问题讨论】:

标签: c++ inline


【解决方案1】:

可能存在内联函数会增加程序大小或移动程序位的边缘情况,从而导致缓存未命中发生在以前没有发生的地方。这并不常见,因为缓存旨在处理最常见的情况,并且与大多数热点相比非常大。

【讨论】:

  • 游戏机也是这样的边缘案例吗?
  • @fridolin69 这一切都取决于控制台中使用的处理器。多年来,所有处理器都有非常相似的缓存系统,所以我不能说它会产生很大的不同。你有什么具体情况想知道吗?
  • 没有具体的控制台我只是在准备考试时偶然发现它。
【解决方案2】:

在现代 C++ 编译器中没有强制内联函数的标准方法,所以这是一个有争议的问题。但是,假设您使用编译器特定的功能来强制内联(并且编译器不会忽略它),它不会导致性能下降,但会导致可执行文件大小增加,因为有更多相同代码的副本。

编辑:根据下面的评论,应该提到确实存在极不可能的极端情况,您的代码可能会在附近执行相同内联函数的不同副本,从而降低指令缓存的效率。这会显着影响性能的可能性极小,但在某些极端情况下可能会。

【讨论】:

  • 您不能使用标准 cpp,但您可以使用编译器特定的关键字,例如 VS 中的 __forceinline
  • @fridolin69 关于编译器特定内联的好点。我将编辑我的答案以明确说明没有标准方式,这是我的意图。
  • @fridolin69 如果需要,编译器可能仍会忽略__forceinline 关键字("You cannot force the compiler to inline a particular function, even with the __forceinline keyword")。
  • 不知道为什么这么多反对票,答案似乎合理
  • 您的答案几乎就在那里,但您没有回答它如何导致性能不佳,它可以。因为函数是被复制的,所以它会使代码变大,这会损害 CPU 的指令缓存。 i-cache 并没有那么大,它需要获取的代码越多,运行速度就越慢。
【解决方案3】:

我们应该退后一步,尝试解释 CPU 的工作原理。通常它们有不同的缓存,一个用于代码,它告诉 CPU 需要执行的指令,另一个用于数据,用于应用操作。

数据缓存未命中是“容易”解决的,尽量使用最小的数据结构,将你更频繁访问的成员放在一起......

指令缓存未命中更难理解和解决,这也是人们普遍认为 C++ 中的多态行为比正常函数调用慢的原因。基本上,CPU 将在其缓存中预取存储在您尝试执行的执行点附近的指令,如果所有内容都是内联的,则只有更多数据并且无法预取所有内容,从而导致缓存未命中.请注意,这只是一个简单的案例,根据我的经验,我遇到了模板实例化的问题,这些问题会生成大量代码,导致性能比仅具有简单的虚拟调用和不太深的对象层次结构更慢。

正如 Alexandrescu 一直指出的那样,您应该始终为代码计时

来源: What Every Programmer Should Know About Memory

【讨论】:

    猜你喜欢
    • 2012-12-16
    • 2012-07-31
    • 2011-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-13
    • 2019-11-09
    • 2021-10-20
    相关资源
    最近更新 更多