如何知道在指令之间需要多少NOP来修复数据危害?我目前的理解是,如果第二条指令的操作数依赖于第一条指令的目的地,我们需要等到第一条指令到达数据可用的特定阶段。
例如:
添加$t1$t2$t3
低于$t5$t1$t4
我知道我必须等到第一条指令到达WB阶段,所以我至少需要3个NOP或介于两者之间的指令。
但是,如果第一条指令被更改为存储、加载或立即指令,该怎么办?如果第二条指令被改了怎么办?我用的是帕特森和轩尼诗的书,而我教授的讲座并没有真正帮助我更容易理解。如有任何帮助,我们将不胜感激。
NOP实际上是处理器指令,在构建程序时,编译器或汇编语言程序员必须将其插入指令序列。
只有在删除转发和停滞硬件的情况下,才需要插入NOP,所以这个问题并不真正适用于真正的硬件,也许适用于一些假设的硬件。
另一方面,暂停是处理器实现的一种有效方法,可以减轻写后读取(RAW(等危险——有时是绝对必要的,有时是转发的糟糕替代方案。
通常,在以寄存器为目标的指令(如add
(和使用该结果的指令之间,为了使第二条指令读取正确的数据,在不进行转发的情况下需要两个或三个暂停周期。
2个周期还是3个周期取决于内部实现,问题是:ID阶段是否可以读取与WB阶段写入寄存器重叠的寄存器——它是否可以读取在同一周期中写入的值。如果答案是肯定的,则只需要2个周期以上的暂停,但如果答案是否定的,则需要3个周期的暂停来完全完成向寄存器堆的WB周期写入,并允许随后的ID读取从寄存器堆读取相同的结果。
大多数MIPS实现将描述WB阶段是简单的并且可以在周期的前半部分中完成,并且ID阶段也是简单的并且能够在同一周期的后半部分中完成。这意味着,对于在同一周期中发生的WB写入和ID读取,ID读取将能够看到由WB写入写入的值。由于重叠起到了理想效果的作用,因此只需要2个失速循环。
为什么WB阶段很简单?因为没有什么要计算的(没有加法/减法,没有查找(,并且写入所需的值在周期的最开始就可用。因此,该值几乎立即进入寄存器,并且寄存器堆的ID读取将仅通过电路的设置来获取新写入的值。因此,上半场/下半场甚至不一定是严格要求的。