tom*_*ycc 4 cpu cpu-architecture riscv
当我阅读RISC-V用户级ISA手册时,我注意到它说:“ OpenRISC具有条件代码和分支延迟时隙,这会使更高性能的实现复杂化。” 因此RISC-V没有分支延迟槽RISC-V用户级ISA手动链接。而且,维基百科表示,大多数新的RISC设计都省略了分支延迟时隙。为什么大多数较新的RISC体系结构逐渐忽略分支延迟时隙?
引用Henessy和Patterson(计算机体系结构和设计,第5版)。
谬论:您可以设计一个完美的体系结构。
所有体系结构设计都需要在一组硬件和软件技术的上下文中进行权衡。随着时间的流逝,这些技术可能会发生变化,并且在做出决定时可能是正确的决定看起来像是错误。(...)RISC集中营中的一个示例是延迟分支。用五级流水线控制流水线危害很简单,但对于流水线较长的处理器,每个时钟周期发出多条指令,这是一个挑战。
实际上,就软件而言,延迟分支仅具有缺点,因为它会使程序更难读取,效率也较低,因为该插槽经常被点填充。
在硬件方面,这是一项在八十年代具有一定意义的技术决策,当时流水线为5或6级,无法避免单循环分支损失。
但是目前,管道变得更加复杂。最近的奔腾μ体系结构的分支惩罚为15-25个周期。因此,一个指令延迟分支是没有用的,并且试图用15条指令延迟分支来隐藏此延迟槽是毫无意义的,并且显然是不可能的(这将破坏指令集兼容性)。
并且我们开发了新技术。分支预测是一项非常成熟的技术。使用目前的分支预测器,错误预测远远低于具有无用(nop)延迟时隙的分支数量,因此即使在6周期计算机(如nios-f)上,错误预测也更加有效。
因此,延迟分支在硬件和软件方面的效率较低。没有理由保留它们。
延迟槽只对短的有序标量管道有用,对高性能超标量管道没有帮助,尤其是对于乱序执行的管道。
它们使异常处理显着复杂化(对于硬件和软件),因为您需要记录当前程序计数器并单独记录下一个 PC 地址,以防延迟槽中的指令发生异常。
它们也使6 级标量或超标量 MIPS 中的误预测需要杀死多少条指令变得复杂?通过引入多种可能性,例如分支延迟指令已经在管道中并且不需要被终止,而仍然在等待 I-cache 未命中,因此重新引导前端需要等到它获取分支之后-延迟指令。
分支延迟槽在架构上公开了有序经典 RISC 管道的实现细节,以提高这种 uarch 的性能,但其他任何事情都必须解决它。如果您的 uarch 是标量经典 RISC ,它只会避免从采用的分支(即使没有分支预测)中提取代码气泡。
即使是现代的有序 uarch 也需要分支预测以获得良好的性能,内存延迟(以 CPU 时钟周期衡量)远高于早期 MIPS。
(有趣的事实:MIPS 的 1 个延迟槽足以隐藏 R2000 MIPS I 上的总分支延迟,这要归功于将其降低到 1 个周期的巧妙设计。)
分支延迟槽不能总是由编译器以最佳方式填充,因此即使我们可以在没有显着开销的高性能 CPU 中实现它们,就每条指令完成的总工作而言,它们会降低吞吐量。程序通常需要执行更多的指令,而不是更少,在 ISA 中带有延迟槽。
(虽然有时在比较和分支之后做一些无条件的事情可以允许重用寄存器而不是需要新寄存器,但在没有标志的 ISA 上,例如 MIPS,分支指令直接测试整数寄存器。)