assembly - MIPS 语言避免管道停顿

标签 assembly mips pipeline cpu-architecture

关于 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 $6 from I1 to I3. Do you??

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

关于assembly - MIPS 语言避免管道停顿,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33935604/

相关文章:

assembly - "push ebp"在 x86 汇编中意味着什么?

顶部带有 %include 的程序集 - 打印输出意外结果 : just an "S"

c++ - 从 arm 程序集调用 c 函数时堆的地址发生了变化?

eclipse - View 中的自定义 Eclipse 快捷方式

algorithm - 流水线算法定义

c - ARM 程序集 - 为什么我的应用程序在将 r7 归零时崩溃?

assembly - 如何在 MIPS 中遍历数组?

algorithm - 用mips写俄罗斯农民乘法

c++ - 由于未对齐的内存地址,内存地址是否会被破坏?

python - 为什么在 scikit-learn 中使用 make_pipeline 时出现 'last step of pipeline' 错误?