ami*_*mit 7 c++ performance cpu-registers
来自http://www.boost.org/community/implementation_variations.html
"...编码差异,例如将类从虚拟成员更改为非虚拟成员或删除间接级别不太可能产生任何可衡量的差异,除非深入内部循环.即使在内部循环中,现代CPU经常执行此类操作在相同数量的时钟周期内竞争代码序列!"
我试图理解"甚至在内循环"部分.具体来说,CPU在相同数量的时钟周期内执行哪些机制来执行两个代码(虚拟与非虚拟或额外的间接级别)?我知道指令流水线和缓存,但是如何在与非虚拟调用相同的时钟周期内执行虚拟调用?间接是如何"丢失"的?
缓存(例如分支目标缓存)、并行加载单元(管道的一部分,但也包括“未命中”之类的东西,不会使管道停顿)和乱序执行可能有助于将load- load-转换branch为更接近固定的东西branch。流水线的解码或分支预测阶段中的指令折叠/消除(正确的术语是什么?)也可能有所贡献。
不过,所有这些都依赖于很多不同的东西:有多少个不同的分支目标(例如,您可能会触发多少个不同的虚拟重载),您循环了多少个东西(分支目标缓存是否“温暖”? icache/dcache 怎么样?),虚拟表或间接表如何在内存中布局(它们是否对缓存友好,或者每个新的 vtable 加载是否可能驱逐旧的 vtable?),缓存是否由于以下原因而反复失效多核乒乓球等...
(免责声明:我绝对不是这方面的专家,我的很多知识都来自研究有序嵌入式处理器,所以其中一些是推断。如果您有更正,请随时发表评论!)
确定特定程序是否会出现问题的正确方法当然是进行分析。如果可以的话,请借助硬件计数器来实现这一点——它们可以告诉您很多有关管道各个阶段所发生情况的信息。
编辑:
正如 Hans Passant 在上述评论Modern CPU Inner Loop Indirection Optimizations中指出的那样,让这两件事花费相同时间的关键是能够在每个周期有效地“退休”多个指令。指令消除可以对此有所帮助,但超标量设计可能更重要(未命中命中是一个非常小的且具体的示例,完全冗余的负载单元可能是更好的示例)。
让我们采取一种理想的情况,假设直接分支只是一条指令:
branch dest
Run Code Online (Sandbox Code Playgroud)
...间接分支是三个(也许你可以得到两个,但它大于一个):
load vtable from this
load dest from vtable
branch dest
Run Code Online (Sandbox Code Playgroud)
让我们假设一种绝对完美的情况:*这个和整个 vtable 都在 L1 缓存中,L1 缓存足够快,可以支持两个加载的每指令成本摊销一个周期。(您甚至可以假设处理器对负载进行了重新排序,并将它们与较早的指令混合在一起,以便有时间让它们在分支之前完成;这对于本例来说并不重要。)还假设分支目标缓存很热,并且没有管道分支的刷新成本,并且分支指令归结为单个周期(摊销)。
因此,第一个示例的理论最短时间为 1 个周期(已摊销)。
第二个示例的理论最小值(缺少指令消除或冗余功能单元或允许每个周期退出多条指令的东西)是 3 个周期(有 3 条指令)!
间接加载总是会更慢,因为有更多的指令,直到您进行诸如超标量设计之类的允许每个周期退出多条指令的设计。
一旦你有了这个,两个例子的最小值就会变成 0 到 1 个周期之间的值,前提是其他一切都是理想的。可以说,第二个示例必须有比第一个示例更理想的环境才能真正达到理论最小值,但现在这是可能的。
在您关心的某些情况下,您可能不会达到这两个示例的最小值。要么分支目标缓存变冷,要么虚函数表不在数据缓存中,要么机器无法重新排序指令以充分利用冗余功能单元。
...这就是分析的用武之地,无论如何,这通常是一个好主意。
首先,您可以对虚拟技术抱有轻微的偏执。请参阅Noel Llopis 关于面向数据设计的文章、优秀的面向对象编程陷阱幻灯片以及Mike Acton 的脾气暴躁但富有教育意义的演示。现在,如果您正在处理大量数据,您会突然进入 CPU 可能已经满意的模式。
像虚拟这样的高级语言特性通常是表达性和控制性之间的权衡。不过,老实说,我认为,只要提高您对虚拟实际功能的认识(不要害怕时不时地阅读反汇编视图,并且一定要看看您的 CPU 架构手册),您就会倾向于使用它当它有意义时,而不是当它没有意义时,分析器可以根据需要涵盖其余部分。
关于“不要使用虚拟”或“虚拟使用不太可能产生可衡量的差异”的一刀切的说法让我感到不满。现实通常更复杂,要么你会处于一种你足够关心的情况,以至于要分析或避免它,要么你处于另外 95% 的情况,除了可能的教育内容之外,它可能不值得关心。