分支预测能走多远



我知道现代CPU设计中有一个分支预测器试图猜测该去哪个分支。

假设有一个跳转指令将控制流传输到基本块 A 或基本块 B。

如果预测器决定去 A,当实际计算到跳转指令时,发现 B 应该是正确的选择而不是 A,此时,基本块 A 中的执行能走多远?

基本块 A 中的所有指令都已完成执行了吗?还是只执行第一条指令?

我们如何才能找到实际结果并更多地了解分支预测策略?

CPU 假设分支预测是正确的,除非/直到它发现它不是。 (硬件无法检测到"基本块":它不知道何时到达其他指令分支的地址。 反正你也不想停下来。 现代分支预测足够好,可以在无序 CPU 中使用,这通常是正确的,例如 95% 到 99% 的时间。

发现错误预测(或确认正确预测)发生在分支指令本身被解码(无条件直接分支)或执行(有条件和/或间接)时。

如果预测错误,CPU 必须将前端(获取/解码)重新引导到正确的路径。 在有序 CPU 上,在分支本身执行之前,分支之后的任何指令都无法执行,因此始终只需重新启动获取/解码即可。

(按顺序超标量实际上可以在分支之后执行指令,但是按顺序管道使得在它到达写回并实际更改架构状态之前相对容易压缩。 存储可能是最棘手的,因为您需要丢弃该存储缓冲区条目;它的可见影响将是内存,而不是写回寄存器。 但无论如何,除了将执行与缓存未命中存储分离以及其他原因之外,这也是为什么即使是按顺序流水线的 CPU 也有存储缓冲区的原因。


或者对于具有推测性执行的无序 CPU,允许来自错误路径的指令在条件或间接分支等待其输入时实际执行,它必须刷新后端并从正确的执行路径重新启动问题。

(通过快速恢复和分支顺序缓冲区,即使分支之前的某些指令尚未完成执行,也会发生这种情况。 例如,在循环体中具有简单循环条件和较长依赖链的循环中,因此循环条件依赖链的执行可以提前运行,并在循环分支失败时在最后一次迭代中发现错误预测,而无需等到该指令准备好停用。 即无需等待循环体执行那么远。

可以同时运行多个分支。当然,任何负载或存储都可能出错。 OoO exec CPU 基本上将所有内容视为投机,直到退休。

运行中未执行分支数量的限制因素可能是分支顺序缓冲区 (BOB) 的大小,在这种情况下,该缓冲区在必须跟踪每个尚未停用的指令的 ROB(重新排序缓冲区)之前填满。

我希望分支可以在执行(确认预测或检测到错误预测并启动恢复)后离开该 BOB,而无需退休。 如果之前检测到错误推测,则分支无论如何都在错误的路径上,因此其输入可能是错误的。 如果相同的分支指令沿着新确定的正确执行路径进入管道,它将再次从前端发出并分配一个新的 BOB 条目。

因此,没有必要将 BOB 条目保留到退休;提前释放它可以让它重新分配给尚未执行的较年轻的分支。 (可能存在一些旧的缓存未命中加载,它不是一堆后续分支的数据依赖项,让 ROB 填充大部分可以在加载最终到达之前完成执行的指令,所有依赖项链和推测都尘埃落定。

典型的(?BOB 大小在 Skylake 中为 48 个条目。 较旧或低端的 CPU 可能具有明显较小的 BOB,以配合其较小的无序推测窗口。

在没有快速恢复(无 BOB)的 CPU 上,其他无序执行资源将是分支推测深度的上限,例如重新排序缓冲区(未停用的操作)和/或调度程序(未执行的操作)。


我们怎么能...了解更多关于分支预测策略的信息?

https://danluu.com/branch-prediction/还不错。 另请参阅Agner Fog的microarch指南(适用于x86)的第一章,其中他介绍了真正的Intel和AMD CPU的功能以及一些背景。 https://agner.org/optimize/

相关内容:现代IT-TAGE预测因子(Haswell和Zen 2及更高版本):

  • 分支预测如何影响 R 中的性能?
  • TAGE 预测准确性通过对更大阵列的循环提高?

相关内容: 管道内容:

  • 当天空湖 CPU 错误预测分支时,究竟会发生什么?
  • 在硬件中断之前如何处理分支错误预测
  • 嵌套分支和推理执行会发生什么情况?
  • 存储缓冲区和再排序缓冲区是否都用于推测指令?
  • 推测执行的 CPU 分支是否可以包含访问 RAM 的操作码?
  • 乱序执行与推测执行

相关内容

  • 没有找到相关文章

最新更新