使用的文档http://www.cs.cornell.edu/courses/cs3410/2011sp/faq/faq_pa1.html
在我们考虑“双重数据风险”(原始规则)之前,我将重写 EX 和 MEM 危害条件(为简单起见删除 !=0 部分):
EX 危险
if (EX/MEM.RegWrite and (EX/MEM.RegisterRd == ID/EX.RegisterRs) # =EX_h_Rs
) ForwardA = 10
if (EX/MEM.RegWrite and (EX/MEM.RegisterRd == ID/EX.RegisterRt) # =EX_h_Rt
) ForwardB = 10
我将调用条件 EX_h_Rs 和 EX_h_Rt 以缩短公式
MEM 危害(原始状态)
if (MEM/WB.RegWrite and (MEM/WB.RegisterRd == ID/EX.RegisterRs)) ForwardA = 01
if (MEM/WB.RegWrite and (MEM/WB.RegisterRd == ID/EX.RegisterRt)) ForwardB = 01
====
我们的示例同时具有两种类型的危险,在(第 1 和第 3)和(第 2 和第 3)之间:
add $1, $1, $2
add $1, $1, $3
add $1, $1, $4
或(问题循环在顶部和底部标有**)
**
add C+A -> A ... A
v ?
add B+A -> A
v
add C+ A -> A
**
根据我的链接,在考虑到双重 EX + MEM 危险后:(不带 !=0 和重新排序的布尔术语),更新了 MEM 危险规则:
让我们修改 MEM 危害的转发条件以处理“双重”数据危害
if (MEM/WB.RegWrite and (MEM/WB.RegisterRd = ID/EX.RegisterRs) and
not (EX/MEM.RegWrite and (EX/MEM.RegisterRd == ID/EX.RegisterRs))
)
ForwardA = 01
if (MEM/WB.RegWrite and (MEM/WB.RegisterRd = ID/EX.RegisterRt) and
not (EX/MEM.RegWrite and (EX/MEM.RegisterRd == ID/EX.RegisterRt))
)
ForwardB = 01
或者同样使用 EX_h_* 的短记录
if (MEM/WB.RegWrite and (MEM/WB.RegisterRd = ID/EX.RegisterRs) and
not ( EX_h_Rs )
)
ForwardA = 01
if (MEM/WB.RegWrite and (MEM/WB.RegisterRd = ID/EX.RegisterRt) and
not ( EX_h_Rt )
)
ForwardB = 01
意思是:
尝试从 MEM/WB 转发到 EX;如果没有从 EX/MEM 流水线寄存器转发到相同的输入操作数。
还是一样
甚至不要尝试从 MEM/WB 转发到 EX;如果已经从 EX/MEM 转发了更新的结果。
我会尝试说明:
add C+A -> A A'
v? (forwarding to 3rd instruction)
A -> A''
v?
add C+A -> A
所以,对于第三条指令,原始规则会说,第一条指令中的A' 和第二条指令中的A'' 都应该被转发(但不能同时从两个源提供多路复用器)。并且修改 MEM 危险条件表明,如果有更新的 A'' 的主动转发,则不应尝试转发 A'。
所以; 你的图是对的, 会有2个EX危害转发;但如果已经有 EX Hazard 转发活动,则不应尝试 MEM 危险转发。