早期千兆赫时代的 AMD 处理器每次调用函数时都会损失 40 个周期
呵呵。。那么大。。
有一种“间接分支预测”方法,有助于预测虚函数跳转,如果前段时间有相同的间接跳转。第一个和错误预测的 virt 仍然会受到惩罚。功能跳转。
支持从简单的“当且仅当前一个间接分支完全相同时预测正确”到非常复杂的两级数十或数百条目,其中检测单个间接 jmp 指令的 2-3 个目标地址的周期性交替。
这里有很多进化...
http://arstechnica.com/hardware/news/2006/04/core.ars/7
首次引入 Pentium M: ... 间接分支预测器。
间接分支预测器
因为间接分支从寄存器加载它们的分支目标,而不是像直接分支那样让它们立即可用,所以它们很难预测。Core 的间接分支预测器是一个表,它存储有关前端遇到的每个间接分支的首选目标地址的历史信息。因此,当前端遇到间接分支并将其预测为被占用时,它可以要求间接分支预测器将其引导到分支可能想要的 BTB 中的地址。
http://www.realworldtech.com/page.cfm?ArticleID=rwt051607033728&p=3
间接分支预测最初是在 Intel 的 Prescott 微架构中引入的,后来是 Pentium M.
16-50% 的分支错误预测是间接的(平均 29%)。间接分支错误预测的真正价值在于许多使用解释器的较新的脚本或高级语言,例如 Ruby、Perl 或 Python。其他常见的间接分支常见罪魁祸首包括虚函数(在 C++ 中使用)和对函数指针的调用。
http://www.realworldtech.com/page.cfm?ArticleID=RWT102808015436&p=5
AMD 采用了其中的一些改进;例如在巴塞罗那和以后的处理器中添加间接分支预测器数组。然而,与 Core 2 相比,K8 的分支预测器更老且更不准确。
http://www.agner.org/optimize/microarchitecture.pdf
3.12 旧处理器上的
间接跳转 间接跳转、间接调用和返回每次都可能转到不同的地址。间接跳转或间接调用的预测方法是,在 PM 和 K10 之前的处理器中,简单地预测它将转到与上次执行时相同的目标。
和相同的 pdf,第 14 页
间接跳转预测 间接跳转或调用是具有两个以上可能目标的控制转移指令。C++ 程序可以生成间接跳转或调用......一个虚函数。通过将寄存器或内存变量或索引数组指定为跳转或调用指令的目标,在汇编中生成间接跳转或调用。许多处理器只为间接跳转或调用创建一个 BTB 条目。这意味着它将始终被预测为与上次相同的目标。随着多态类的面向对象编程变得越来越普遍,预测具有多个目标的间接调用的需求也在增长。这可以通过为遇到的每个新跳转目标分配一个新的 BTB 条目来完成。历史缓冲区和模式历史表必须为每个跳跃事件提供多于一位信息的空间,以便区分两个以上的可能目标。PM 是第一个实现此方法的 x86 处理器。p 上的预测规则。12 仍然适用,但可以完美预测的理论最大周期为 mn,其中 m 是每个间接跳跃的不同目标的数量,因为有 mn 个不同的可能的 n 长度子序列。但是,如果超过 BTB 或模式历史表的大小,则无法达到该理论最大值。12 仍然适用,但可以完美预测的理论最大周期为 mn,其中 m 是每个间接跳跃的不同目标的数量,因为有 mn 个不同的可能的 n 长度子序列。但是,如果超过 BTB 或模式历史表的大小,则无法达到该理论最大值。12 仍然适用,但可以完美预测的理论最大周期为 mn,其中 m 是每个间接跳跃的不同目标的数量,因为有 mn 个不同的可能的 n 长度子序列。但是,如果超过 BTB 或模式历史表的大小,则无法达到该理论最大值。
Agner 的手册对许多现代 CPU 中的分支预测器以及每个制造商 (x86/x86_64) 的 cpu 中预测器的演变进行了更长的描述。
还有很多理论上的“间接分支预测”方法(看谷歌学者);甚至维基也说了一些话http://en.wikipedia.org/wiki/Branch_predictor#Prediction_of_indirect_jumps /
对于来自agner's micro的Atoms:
间接分支的预测 根据我的测试,Atom 没有间接分支的模式预测器。预计间接分支将与上次相同的目标。
因此,对于低功耗,间接分支预测并不是那么先进。Via Nano 也是如此:
预计间接跳跃将前往与上次相同的目标。
我认为,较短的低功耗 x86 管道具有较低的惩罚,7-20 滴答。