使用相同的寄存器执行 ADD 和 SW 时 MIPS 中的数据危害?

Data hazard in MIPS when performing ADD and SW with the same registers?

MIPs Datapath Im referring to 假设我们这里有 MIPs 汇编程序,有 5 阶段流水线 IF/ID/EXE/MEM/WB,没有转发,并假设所有指令都经过每个阶段,即使它可能不会产生任何有意义的结果:

...
add $t0, $s1, $s0
sw  $t0, 0($s2)
...

是否存在RAW数据危害? 我目前的思考过程是因为:
$t0 <- $s1 + $s0
内存[0 + $s2] <- $t0

然后它是一个 Read After Write 因为我们首先写入 $t0(在添加时)然后我们读取 $t0 以将其放入内存。此外,当 SW 在 ID 时,ADD 在 ALU/EXE 阶段执行加法。因此,在 ADD 可以写回结果之前,SW 的 ID 阶段会反省 $t0 的值。

我知道有一个类似的问题: Is there an execute-store data hazard in MIPS?
但我的情况非常具体,这对我没有太大帮助,因为他假设指令可以在不使用某些阶段的情况下执行。

这确实是一个管道危险,要缓解需要旁路。观察到第 2 条指令所需的 value 实际上恰好在需要时可用,这是旁路的基础。在一个简单的流水线中,计算出的值在写入目标寄存器之前是不可用的,这是在实际计算出该值之后的一个周期左右;然而,通过旁路,我们可以更快地重定向计算值(放弃寄存器写入)。

是的,当然存在 RAW 风险。一条指令读取前一条指令的结果,间隔远小于流水线长度。维基百科:https://en.wikipedia.org/wiki/Classic_RISC_pipeline#Data_hazards

Data hazards occur when an instruction, scheduled blindly, would attempt to use data before the data is available in the register file.

像 R2000 这样的经典商业 MIPS 有旁路转发,不会停止,因为它的转发逻辑检测到危险(仍然 存在 ) 并将 EX 结果从 add 转发到 sw 的寄存器读取复用器。因此,继续前进到流水线的其余部分,该指令具有 $t0 的转发值和 $s2 的寄存器文件值。 https://en.wikipedia.org/wiki/Classic_RISC_pipeline#Solution_A._Bypassing

如果没有旁路转发,是的,您实际上必须停止。假设 SW 仍然在正常时间从寄存器文件中读取它的两个输入操作数,在 ID 阶段。 IDK 如果您可以让存储延迟读取它们的数据寄存器(在 MEM 状态开始时)以将停顿周期数减少 1 是合理的,但这可能需要寄存器文件中的额外读取端口,因为 ID 阶段可能还要阅读 2 条说明。

您的管道仍然需要检测 危险并能够为此停止 (https://en.wikipedia.org/wiki/Classic_RISC_pipeline#Solution_B._Pipeline_interlock)。简单 ALU 指令的有效延迟小于 1 个周期是非常糟糕的,这就是为什么所有现实世界的 RISC 管道都进行转发而不是仅仅检测和停止。编译器有足够的时间安排代码来填充加载延迟和分支延迟槽,而不必为每个简单的 ALU 指令隐藏延迟!