避免流水线停顿的 MIPS 语言

MIPS language to avoid pipeline stalls

关于 pattersson 书中提到的 MIPS 汇编语言,我对在指令之间插入 NOP 以避免流水线停顿有疑问。

考虑以下代码

lw   $s5, -16($s5)
sw   $s5, -16($s5)
add  $s5, $s5, $s5

我们看到在 lwsw 之间存在 $s5 的 RAW 风险。在 swadd 之间也存在 $s5 的 WAW 风险。所以我们必须插入两个 NOP 以避免停顿。也就是说,流水线图是

lw      IF     ID     EX     MEM     WB
sw             IF     ID     ---     EX     MEM     WB
add                   IF     ID      EX     MEM     --     WB

sw要执行时,必须等待lw将数据放入寄存器。因此,存在一个泡沫。另外,当add要写入最终结果时,必须等待上一条指令(sw)完成。那又是一个泡泡

所以修改后的代码是

lw
NOP
sw
NOP
add

但解决方案提出如下代码

lw
NOP
NOP
sw
add

哪个是正确的?我想我的!

假设一个相当标准的管道,不存在 WAW 风险,它在程序代码中可能看起来有点风险(在对同一寄存器进行多次写入的意义上),但没有机制ADD 可以在 LW 之前(或期间)完成(这意味着它在输入可用之前计算结果)。 SW 不写入寄存器,所以没关系,但 ADD 也无法在此之前完成。实际上标准管道中根本不存在 WAW 危害,因为指令只是按顺序回写。

您针对 RAW 危害的解决方案假设存在 WB->EX 转发,根据他们的解决方案判断,没有。没有转发器,最快可以使用结果是读取指令的 ID 与写入指令的 WB 对齐。


Why (WB) and (EX) are not executed in one cycle?

因为它不起作用。它在问题 a 中也不起作用,所以我不确定那里发生了什么。这道题的前提是没有转发到EX,所以和前面一样,一个值产生后最快可以使用的是读指令的ID和写指令的WB对齐。 EX 只是从 ID/EX 流水线寄存器读取它的输入。

Also, for (a), I don't see any WAR on from I1 to I3. Do you??

不会,因为I1和I3都没有修改$6,所以不可能有任何危险。 RAR 不是危险。