关于 pattersson 书中提到的 MIPS 汇编语言,我有一个关于在指令之间插入 NOP 以避免管道停顿的问题。
考虑以下代码
lw $s5, -16($s5)
sw $s5, -16($s5)
add $s5, $s5, $s5
我们发现 lw
和 sw
之间的 $s5 存在 RAW 风险。 sw
和 add
之间的 $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 $6 from I1 to I3. Do you??
不会,因为 I1 和 I3 都不会修改 $6,所以不可能有任何危险。 RAR 不是危险。
关于assembly - MIPS 语言避免管道停顿,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33935604/