-1

有人可以帮我理解为什么在第 1 行和第 3 行之间我们不需要转发(1 和 2 之间没有绿色箭头)

我认为我们需要它,因为 sub 使用 add 确定的 t0 的值,并且两者都在同时读取和写入该值。(准确地说,添加的写入发生在时钟上升时更晚)

4

1 回答 1

1

您是正确的,在第三条指令 ( sub) 中,已经在解码阶段读取了不正确的(例如陈旧的)值,因此需要诸如转发之类的缓解措施。

事实上,该sub指令读取了两个不正确的(陈旧)值,一个用于第一个操作数,t0一个用于第二个操作数,t3因为该寄存器已被前一条指令更新。

第一次实际寄存器更新(t0by add)在第 5 周期(基于 1 的计数)中可用,但解码sub发生在第 4 周期。需要转发:这里可能是从 W 阶段add到 ALU 阶段的- 或sub- 可以从 的 M 阶段add到 的 D 阶段完成sub

只有在(第 4 条指令,未显示)之后的下一个周期中,解码才能从较早指令的 W 阶段获得正确的最新值——如果 W 阶段与后续指令的 D 阶段重叠,则无需转发,因为W 阶段在周期的早期完成,而 D 阶段能够获得该结果。


在指令 2(写入器)和指令 3(读取器)之间还有一个简单的 ALU-ALU 依赖关系,即写后读风险,t3图中没有显示出来,因此这是很好的证据,即图表在显示所有危险方面是不完整的。


有时,教育工作者只展示了写后读危险的最明显例子。还有许多其他经常被忽视的危险。

另一个涉及负载危险。通常,负载危险被视为既需要前进又需要失速。如果在 ALU 的下一条指令中使用了加载结果,则会出现这种情况。但是,如果加载指令之后是存储指令(存储加载的数据),则从 M(加载)到 M 存储的转发可以减轻这种危险而不会停顿(与 X 到 X 转发可以减轻的方式非常相似)和 ALU 依赖风险)。

因此,我们可能会注意到存储指令有两个寄存器源,但在 M 阶段之前实际上并不需要用于存储值的寄存器,而在 X (ALU) 阶段需要用于基地址计算的寄存器。(这使得 store 与同样具有两个寄存器源的存储有所不同,add因为 X 阶段都需要这两个源。)

于 2021-01-27T01:36:04.617 回答