为什么不建议使用分支延迟槽或将其过时?

时间:2019-02-16 15:03:46

标签: cpu cpu-architecture riscv

当我阅读RISC-V用户级ISA手册时,我注意到它说:“ OpenRISC具有条件代码和分支延迟时隙,这会使更高性能的实现复杂化。”因此RISC-V没有分支延迟槽RISC-V User-Level ISA manual link。此外,Wikipedia说,大多数较新的RISC设计都省略了分支延迟时隙。为什么大多数较新的RISC体系结构都逐渐省略分支延迟时隙?

3 个答案:

答案 0 :(得分:5)

引用Henessy和Patterson(计算机体系结构和设计,第5版)

  

Fallacy:您可以设计一个完美的体系结构。
  所有体系结构设计都需要在一组硬件和软件技术的上下文中进行权衡。随着时间的流逝,这些技术可能会发生变化,并且在做出决定时可能是正确的决定看起来像是错误。 (...)RISC阵营中的一个例子   是延迟分支。控制管道很简单   五级流水线带来的危害,但对于较长时间的处理器却是一个挑战   每个时钟周期发出多个指令的流水线。

实际上,就软件而言,延迟分支仅具有弊端,因为它经常使空位占用插槽,从而使程序更难阅读,效率更低。

就硬件而言,这是一项在八十年代具有一定意义的技术决策,当时流水线为5或6级,无法避免单循环分支代价。

但是目前,管道要复杂得多。最近的奔腾μ体系结构的分支惩罚为15-25个周期。因此,一个指令延迟分支是没有用的,并且试图用15条指令延迟分支来隐藏此延迟槽是毫无意义的,而且显然是不可能的(这将破坏指令集的兼容性)。

我们已经开发了新技术。分支预测是一项非常成熟的技术。使用目前的分支预测器,错误预测远远低于具有无用(nop)延迟时隙的分支数量,因此即使在6周期计算机(如nios-f)上,错误预测也更加有效。

因此,延迟分支在硬件和软件方面的效率较低。没有理由保留它们。

答案 1 :(得分:4)

延迟插槽仅对短的有序标量流水线有用,而对高性能超标量无济于事,特别是在无序执行的情况下。

它们(对于硬件和软件)使异常处理变得非常复杂,因为如果延迟槽中的指令发生异常,则需要记录当前的程序计数器和下一个PC地址。


分支延迟插槽在体系结构上公开了按顺序进行的经典RISC管道的实现细节,以带来这种优缺点的性能优势,但其他任何方法都必须解决。如果您的上位者是classic RISC,则只能避免从已获取分支获取代码气泡(即使没有分支预测)。

即使是现代有序的uem 需要分支预测也能获得良好的性能,并且内存延迟(以CPU时钟周期衡量)远高于早期MIPS时代。


分支延迟槽不能总是由编译器最佳地填充,因此即使我们可以在高性能CPU中实现它们而又没有显着的开销,但它们却以每条指令完成的总工作量为代价。程序通常需要执行更多的指令,而不是更少的指令,并且在ISA中具有延迟槽。

(尽管有时在比较和分支之后做一些无条件的 操作,但它可以在ISA上没有MIPS之类的标志的ISA上重用寄存器,而不需要新的寄存器,分支指令直接测试整数寄存器)

答案 2 :(得分:2)

分支延迟时隙是最早的单次有序RISC实现中的一种性能变通方法。早在这些体系结构的第二种商业实现中,就已经很清楚,延迟时隙和单一条件码的概念都将成为障碍。当我们在HaL完成64位SPARC架构时,寄存器窗口已添加到该列表中。合并的挑战就足够了,我们建议使用动态二进制转换来支持SPARC32,这样就可以避免遗留的负担。那时,它们的成本为芯片面积的40%和指令发布率的20%至25%。

现代处理器实现严重混乱(通过“寄存器重命名”或“ Tomasulo算法”读取),动态调度以及在许多情况下是多次执行。结果,延迟分支已经从性能增强变成了复杂性,为了兼容,指令排序单元和寄存器重命名逻辑必须谨慎地执行。

坦率地说,在SOAR / SPARC或MIPS芯片上也不是一个好主意。延迟分支给调试器中的单步调试,动态二进制翻译器和二进制代码分析带来了有趣的挑战(我一次或一次实现了所有这些)。即使在单发行机上,它们也为异常处理创造了一些有趣的复杂性。早在这些指令集的第二种商业实现中,延迟时隙和单一条件码的概念就已经出现。

Alain关于奔腾的分支机构成本的评论并没有直接转移到RISC零件上,而且这个问题比他建议的要复杂一些。在固定长度的指令集上,很容易实现称为“分支目标缓冲区”的东西,该指令将指令缓存在分支目标处,这样就不会由于分支而引起流水线停顿。在原始的RISC计算机(IBM 603)上,John Cocke合并了一条“准备分支”指令,其目的是允许程序(或更准确地说,是编译器)将可能的目标显式加载到分支目标缓冲区中。在一个好的实现中,BTB中的指令是经过预解码的,这可以缩短流水线的周期,并且可以通过BTB进行几乎完全免费的正确预测的过渡。当时的问题是条件代码和错误预测。

由于BTB和多重问题,分支延迟和分支错误预测延迟的概念需要重新构想。在许多多发行机上实际发生的情况是,处理器沿着分支的两条路径前进-至少在它可以从指令获取单元中当前预加载的高速缓存行或指令中获取指令的同时在BTB中。这样可以减缓分支两侧的指令发出,但还可以让您在分支的两侧进行 progress 。分支解析后,“不应采用”路径被放弃。对于整数处理,这会使您减速。对于浮点,它还不太清楚,因为计算操作需要几个周期。

在内部,一个积极进取的多问题机器很可能在分支时在内部排队三个或四个操作,因此通常可以通过执行这些已排队的指令然后重新构建分支来补偿分支延迟。队列深度。