从http://www.boost.org/community/implementation_variations.html
“...编码差异(例如,将类从虚拟成员更改为非虚拟成员或删除间接级别)不太可能产生任何可测量的差异,除非深入内部循环。甚至在内部循环中,现代CPU经常执行这样的差异。在相同数量的时钟周期内竞争代码序列!”
我试图理解“甚至在内环”部分。具体来说,CPU在相同数量的时钟周期内执行什么机制来执行两个代码(虚拟与非虚拟或附加的间接寻址)?我知道指令的流水线化和缓存,但是如何在与非虚拟调用相同的时钟周期数内执行虚拟调用呢?间接如何“丢失”?
最佳答案
缓存(例如branch target caching),并行加载单元(流水线的一部分,还有“命中未命中”之类的东西不会使管道停顿)和out-of-order execution可能有助于将load
-load
-branch
转换为更接近的东西到固定的branch
。流水线的解码或分支预测阶段中的指令折叠/消除(这是什么合适的术语?)也可能有所帮助。
但是,所有这些都依赖于许多不同的事物:有多少个不同的分支目标(例如,您可能触发多少个不同的虚拟重载),循环了多少事物(分支目标缓存是否“热”)? icache/dcache怎么样?),虚拟表或间接表在内存中的布局方式(它们对缓存友好吗,还是每个新的vtable加载都可能取代旧的vtable?),是否由于以下原因而使缓存重复失效:多核ping-ponging等
(免责声明:我绝对不是专家,我的很多知识都来自研究有序嵌入式处理器,所以其中一些是推断。如果有更正,请随时发表评论!)
当然,要确定特定程序是否会出现问题的正确方法。如果可以的话,在硬件计数器的帮助下进行操作-它们可以告诉您很多有关管道各个阶段中发生的事情的信息。
编辑:
正如汉斯·帕桑特(Hans Passant)在上述注释Modern CPU Inner Loop Indirection Optimizations中指出的那样,使这两件事花费相同时间的关键是能够有效“退休”每个周期多条指令。消除指令可以帮助解决此问题,但是superscalar design可能更重要(未命中是一个非常小的特定示例,完全冗余的负载单位可能是更好的选择)。
让我们假设一个理想情况,并假设直接分支只是一条指令:
branch dest
...而一个间接分支为三个(也许您可以将它分为两个,但大于一个):
load vtable from this
load dest from vtable
branch dest
让我们假设一个绝对完美的情况:*此表和整个vtable都位于L1高速缓存中,L1高速缓存足够快以支持两次加载时每条指令成本摊销一个周期。 (您甚至可以假设处理器对负载进行了重新排序,并将它们与较早的指令混合在一起,以使它们有足够的时间在分支之前完成;在此示例中这无关紧要。)还要假设分支目标缓存很热,并且没有管道刷新分支的成本,并且分支指令下降到单个周期(摊销)。
因此,第一个示例的理论最短时间为1个周期(摊销)。
第二个示例的理论上的最小值,即缺少指令消除或冗余功能单元,或每个周期允许退出多于一条指令的事物,为3个周期(共有3条指令)!
间接加载将总是较慢,因为会有更多的指令,直到您进入超标量设计之类的东西为止,该设计允许每个周期退出多个指令。
一旦有了这一点,只要其他条件都理想,两个示例的最小值就变为0到1个周期之间的值。可以说,要使第二个示例要比第一个示例实际达到理论上的最低水平,必须要有更理想的环境,但是现在有可能。
在您关心的某些情况下,对于任何一个示例,您都可能无法达到该最小值。分支目标缓存将变冷,或者vtable将不在数据缓存中,或者机器将无法重新排序指令以充分利用冗余功能单元。
...这是进行分析的地方,无论如何,这通常是个好主意。
首先,您可以只对虚拟机稍加偏执。参见Noel Llopis's article on data oriented design,出色的Pitfalls of Object-Oriented Programming slides和Mike Acton's grumpy-yet-educational presentations。现在,如果您正在处理大量数据,您突然进入了CPU已经很可能满意的模式。
虚拟语言之类的高级语言功能通常是表达能力和控制能力之间的权衡。老实说,尽管如此,我只是通过增强对虚拟机实际功能的了解(不要害怕不时阅读反汇编 View ,并且一定要看一下CPU的体系结构手册),就会倾向于使用它。在有意义的情况下(而不是在没有意义的情况下),探查器可以在需要时覆盖其余部分。
一刀切的“不使用虚拟”或“虚拟使用不太可能产生可衡量的变化”的说法让我很生气。现实通常更复杂,或者您将处于一种情况,在这种情况下您会足够注意描述或避免出现这种情况,或者您处于其他95%的情况中,除了可能的教育内容外,它可能不值得关注。