如果我内联一个函数。 函数调用体将被复制,而不是向它发出一个call()。 为什么会导致糟糕的表现呢?
编辑:那么由于功能较大而缓存未命中呢? 为什么经验法则"只有最多3行的内联函数"存在呢?
答案 0 :(得分:5)
可能存在一种边缘情况,其中内联函数可以增加程序大小或移动程序的位,以便在之前不存在的情况下发生缓存未命中。这并不常见,因为缓存旨在处理大多数常见情况,并且与大多数热点相比非常大。
答案 1 :(得分:4)
在现代C ++编译器中没有强制内联函数的标准方法,所以这是一个没有实际意义的点。但是,假设您使用特定于编译器的功能强制内联(并且编译器不会忽略它),它不会导致性能不佳,但由于存在相同代码的更多副本,因此会导致可执行文件大小增加。
编辑:根据下面的注释,应该提到一个非常不可能的边缘情况确实存在,您的代码可能在相邻的位置执行相同内联函数的不同副本,从而降低了指令缓存的效率。这会对性能产生显着影响的可能性非常小,但在某些边缘情况下它可能会发生。
答案 2 :(得分:2)
我们应该退后一步,尝试解释CPU的工作原理。通常它们具有不同的高速缓存,一个用于代码,它告诉CPU执行所需的指令,一个用于应用操作的数据。
数据缓存未命中"简单"要解决,尝试使用最小的数据结构,将您更频繁访问的成员放在一起......
指令缓存未命中更难理解和解决,这也是人们普遍认识到C ++中的多态行为比正常函数调用慢的原因。基本上,CPU会在其缓存中预取存储在您尝试执行的执行点附近的指令,如果一切都是内联的,那么只有更多的数据并且它不能够预取所有内容,导致缓存未命中。请注意,这只是一个简单的案例,根据我的经验,我遇到了模板实例化问题,这些问题会产生大量代码,导致性能降低,而不仅仅是简单的虚拟调用和不太深的对象层次结构。
正如Alexandrescu总是指出的那样,你应该总是计算你的代码