为什么非寄存器跳转指令需要分支目标缓冲区?

Why are Branch Target Buffers needed for non register jump instructions?

对于 MIPS 5 级流水线,解码阶段知道分支目标,因为如果分支偏移量在指令中并且您在解码阶段读取寄存器,则可以轻松提取它。

那么对于一个无序的管道,你显然 运行 遇到了像 'jr' 这样的指令的问题,它可能使用了一个尚未计算的寄存器。对于这样的用途,分支目标缓冲区有明确的用途。

但是对于像 'beq' 这样的指令,我看到了分支预测器的必要性,而不是分支目标,因为你已经知道分支偏移量,当然你也知道当前程序计数器,所以你可以轻松想出分支目的地。

寄存器跳转是唯一使用分支目标缓冲区的指令还是我遗漏了什么?

获取阶段需要预测才能知道接下来要获取哪个块。指令缓存有一些延迟,但可以流水线化。 DRAM 有更多的延迟,但仍然可以有多个未完成的请求(取决于内存控制器或缓存的外部级别)。因此 获取阶段需要比当前从 memory/cache.

到达的块提前多个周期的块地址

解码直到获取之后才会发生,因此如果您等到解码时才检测到无条件直接分支的存在,那么这是一个额外的停顿周期。

请参阅 从 x86 的角度了解更多信息(解码成本高且需要多个阶段,因此这一点更为关键)。

另请注意,高性能 CPU 并行解码多条指令,并且通常在提取和解码之间有一个队列以吸收提取气泡。如果获取阶段预测有一个分支(有条件或无条件,无关紧要),它可以排队来自分支目标的指令而不是分支后的指令。


另请参阅 ,了解跳转到下一条指令的巨大序列的 x86 基准测试。 (即相对偏移 = 0)。当序列足够长无法放入 BTB 时,它会变慢。