多周期流水线WAW hazard处理疑问:取消早期WB及“pure”定义
1. 取消前一条指令的WB阶段是否等于丢弃指令?
完全不是。这种方案的应用前提是:前一条指令的写回结果完全不会被后续任何指令用到——比如文档里的ADDD指令,它的目标寄存器会被后一条指令直接覆盖,而且两条指令之间没有任何其他指令读取这个寄存器的值。
举个例子:
ADDD x1, x2, x3 SUBD x1, x4, x5
这里ADDD写x1,SUBD也写x1,且中间没有指令读x1。此时ADDD的结果刚算出来还没写回,SUBD已经算出了新的x1值。这时候跳过ADDD的WB阶段完全没问题,因为最终我们需要的是SUBD的结果,ADDD的写回本来就会被立刻覆盖,属于冗余操作。这种做法不是丢弃指令的执行结果,而是优化掉无意义的写回步骤,不会影响程序正确性。
2. "pure WAW hazard"的定义是什么?
"pure"在这里指的是:两条写同一个寄存器的指令之间,不存在RAW(写后读) hazard——也就是中间没有任何指令读取这个目标寄存器。
它和“两条写指令相邻”没有必然关系,比如下面这种情况也是pure WAW:
ADDD x1, x2, x3 OR x4, x5, x6 SUBD x1, x7, x8
这里ADDD和SUBD都写x1,中间的OR指令不涉及x1,所以不存在RAW hazard,这就是pure WAW。
文档说两种方案都适用的原因是:pure WAW情况下,两条写指令的执行顺序对最终寄存器的值没有影响(因为中间没人读)。你可以选择stall后一条指令,让前一条先写回再执行后一条;也可以直接跳过前一条的WB,让后一条的结果直接写回。两种方式都能保证最终寄存器的值是正确的,所以都适用。
如果是非pure WAW(也就是两条写指令之间有读该寄存器的指令),那绝对不能跳过前一条的WB,因为中间的读指令需要前一条的结果,这时候只能用stall的方式解决。
内容的提问来源于stack exchange,提问作者An5Drama

