MIPS体系结构:NOP(无操作)与危险预防中的数据转发

MIPS体系结构:NOP(无操作)与危险预防中的数据转发,mips,computer-architecture,Mips,Computer Architecture,我在计算机体系结构课程中了解到,在两条相互依赖的指令之间使用多条任意、独立的nop指令可以防止数据危险。这可以在编译器设计的汇编级别完成 避免数据危害的另一种方法是使用数据转发 我有点困惑,这两种选择在性能、速度和硬件方面有什么不同。因为据我所知,数据转发将在硬件级别实现,而nop可以在汇编级别实现 请大家解释一下,如果考虑性能、速度、硬件等因素,哪种方法更好? 谢谢。显然,让编译器将NOP插入到代码流中以填充管道插槽可以简化硬件,从而缩短管道阶段的持续时间或管道深度,减少设计工作量(上市时间、

我在计算机体系结构课程中了解到,在两条相互依赖的指令之间使用多条任意、独立的nop指令可以防止数据危险。这可以在编译器设计的汇编级别完成

避免数据危害的另一种方法是使用数据转发

我有点困惑,这两种选择在性能、速度和硬件方面有什么不同。因为据我所知,数据转发将在硬件级别实现,而nop可以在汇编级别实现

请大家解释一下,如果考虑性能、速度、硬件等因素,哪种方法更好?
谢谢。

显然,让编译器将NOP插入到代码流中以填充管道插槽可以简化硬件,从而缩短管道阶段的持续时间或管道深度,减少设计工作量(上市时间、项目风险、设计成本),或允许在单个芯片上安装完整的处理器内核(这有助于提高性能)。然而,与不使用转发造成的性能损失相比,这一好处微乎其微。对于典型的程序来说,依赖指令的更高延迟是非常糟糕的

具有延迟分支和延迟加载的MIPS R2000提供了结果转发。(。延迟加载很快从MIPS中删除(这是可能的,因为这不会影响正确代码的二进制兼容性)使用延迟指令部分是因为相信编译器可以用有用的指令填充大多数延迟槽,部分是因为相信代码大小的增加相对于硬件的简化并不重要

减少加载操作的延迟是不现实的,因此无论如何管道都需要暂停一个周期。nop的成本在于缓存和内存容量效应(即,较低的代码密度效应),在某些情况下,可以填充单个加载延迟槽

公开管道组织也会对二进制兼容性产生影响。以后的二进制兼容实现必须适应为原始管道组织设计的ISA。单个延迟分支槽对于实现来说相当有效(在大多数情况下,它可以填充有用的指令,并允许零有效延迟分支[即,没有暂停来解决分支或预测失误,并在预测失误时刷新管道]),但当管道加深(或变宽)时,预测或暂停仍然是必要的

如果目标工作负载中存在足够的并行性,则硬件简单性非常重要,并且二进制兼容性不是问题,那么公开一个对动态检测和处理暂停条件支持最低的管道可能是明智的。(还有一些编码NOP的方法可以避免大多数代码大小扩展问题。)具有可靠的足够并行性(无论是指令级还是线程级)可以避免NOP;通过使用指令级并行进行编译器调度,或者通过使用线程级并行进行硬件线程交错


硬件的简单性往往会降低单位工作(以及芯片面积)的能耗,而许多现代设计都受到功耗的限制。在编译时执行优化也很有意义(当它们对延迟的要求较低,并且可以一次而不是每次执行代码时执行)如果附加信息的存储和通信成本不是太高(假设执行优化所需的信息在编译时可用[动态分支预测是动态信息有用的典型示例]).

好吧,基本上,由于硬件是通过feed-forwarding进行优化的,因此不必使用明确声明的软件NOP。但事实并非如此。 虽然事实证明,feed-forwarding有助于减少数据危害,但有些危害是feed-forwarding无法解决的。这是不可能的。
例如

  • beq R1,R5,标签
  • 指示2
  • 在这里,在指令1完成其执行阶段并决定是否分支之前,不会提取指令2。在此之前,必须暂停第2条指令。(暂停2个内存周期)。这是由软件通过发送NOP来完成的。
    随着技术和硬件优化的改进,beq指令可以在寄存器获取/解码阶段通过在获取阶段本身插入一个比较器来完成其执行阶段。即使如此,第二条指令将暂停(现在1个内存周期)。同样需要NOP。

    并非所有暂停都是使用NOP实现的。一些控制单元具有内置机制,用于断言/取消断言数据路径上的某些位,通常将其设置为0,这与NOP具有相同的净效果,但实现方式不同。