如果我们总是可以填充延迟槽而不需要分支预测,这是真的吗?

Is that true if we can always fill the delay slot there is no need for branch prediction?

我正在查看 H&P 第 3 版中的五个阶段 MIPS 流水线(ID、IF、EXE、MEM、WB)。在我看来,分支决策是在 ID 阶段解决的,因此当分支指令到达其 EXE 阶段时,可以正确执行分支后的第二条指令(可以获取)。但这给我们留下了一个问题,即在分支指令之后不久可能仍然浪费了第一条指令。

我也遇到了分支延迟槽的概念,这意味着你想在分支后不久用一些有用的东西填充第一条指令,以及 "harmless" 无论分支是否被采用都是按需执行,分支后的第一条指令没有被浪费。

我的问题是,首先,我的上述理解是否正确?如果它是正确的,那么问题就出在分支预测的概念上,它似乎试图用来自程序将要到达的预测位置的指令来填充第一条指令。但是如果我们总能找到一些指令来填充分支延迟槽,我们就不需要分支预测的特性了,对吧?

事实是,编译器可能并不总能找到一条指令来填充延迟槽。 更重要的是,教学是高度可预测的。

在IF阶段之前,你甚至不知道它是不是分支指令。(你必须从指令内存中取出它)

对于经典的 MIPS (R2000) 流水线,如您所见,分支延迟槽使分支预测变得无用。 (从技术上讲,设计可以将延迟槽指令是否为 nop 的 predictor/indicator 与分支预测器结合起来。这将允许跳过 nop,适度提高正确分支预测的性能。)

然而,处理器流水线通常足够长和足够宽(并且分支条件评估足够延迟)以至于单个延迟槽不足以填补需要 post-分支指令地址和分支方向和目标已知。

例如,后续处理器 MIPS R4000 显着延长了流水线,因此无法及早确定 post 分支指令的位置。设计者选择使用简单的静态预测未采取策略。

如果不关心二进制兼容性,可以添加更多延迟槽。但是,随着插槽数量的增加,找到有用的指令来填充此类插槽的难度也会增加。对于某些循环丰富的代码,定期填充两个延迟槽可能是可行的,我认为至少一个 DSP 有两个延迟槽。

分支预测也可用于将提取与执行分离,这样即使无法评估条件(例如,取决于数据高速缓存未命中或除法等高延迟操作的结果),提取也可以继续。这种解耦可用于尽早生成指令缓存未命中(隐藏它们的一些延迟)并减少不同阶段可变吞吐量的影响(因此当后期停止或吞吐量减少时,较早的阶段可以继续以最大吞吐量运行,并且缓冲的指令然后可以隐藏后面的停顿或减少早期阶段的吞吐量)。

在一个 mips 核心中,像这样具有零等待状态的随机访问 ram 肯定。但是根据提取的实现方式和背后的缓存,您可能仍然 want/need 分支预测的概念可以更早地开始这些提取。管道只是更大系统的一小部分。系统总线通常不是单周期这里是我的地址我想在这个周期结束时得到我的数据,有地址总线和数据总线以及交叉它们的标签所以你可以同时进行多个交易,就像管道一样尝试优化数据总线的带宽,因为知道远端的外围设备和内存对于该总线来说太慢了。

预测 "could" 可用于协助这些其他功能更快或更有效地将指令送入管道。

虽然从学术意义上讲,插槽的想法是给管道一个循环,以沿着另一条执行路径切换齿轮。如果管道的传入端可以在每个时钟周期提供它想要的任何随机东西,它实际上只会为您节省。这不是真实世界。

另一种学术解决方案是对每条指令进行条件执行,您可以构建执行序列以保持管道充满而不必冲洗或停止......同样,只要管道能够跟上...arm 在新的 64 位指令集中放弃了条件指令的想法。 some/newer mips 你可以禁用分支 shadow/delay 插槽。