Dependence types
Flow dependence (RAW)
Read after write: instruction reads a value that instruction writes.
add $t0, $t1, $t2
sub $t3, $t0, $t4The second instruction needs the value produced by the first one. This is a true data dependence, so it cannot be removed by simple renaming. For solution see Handling flow dependences
Anti-dependence (WAR)
Write after read: instruction reads a location that instruction later writes.
sub $t3, $t0, $t4
add $t0, $t1, $t2The later write must not happen too early, otherwise the first instruction would read the wrong value. This is a name dependence, not a true flow of data. It can usually be removed by register renaming.
Output dependence (WAW)
Write after write: two instructions write the same location
add $t0, $t1, $t2
sub $t0, $t3, $t4The final visible value of $t0 must come from the second instruction.
This is also a name dependence, and it can usually be removed by register renaming.
NOTE
register renaming is a central idea in out-of-order processors. It removes false dependences, so the scheduler can execute more instructions in parallel.
Handling flow dependences
There are several fundamental ways to handle a flow dependence:
- detect it and wait until the value is available in the register file. Add
nopinstructions to create bubbles. - detect it and forward / bypass the value to the dependent instruction
- detect it and eliminate the dependence at the software level
- detect it and move it out of the way by executing independent instructions first
- predict the needed value, execute speculatively, and later verify
- do something else while waiting, for example fine-grained multithreading
Combinational dependence check logic
The hardware compares source and destination registers with combinational logic and then decides to stall, forward, or proceed. This is simple and fast for small pipelines, but it scales poorly.
Scoreboarding
A scoreboard keeps centralized status information about instructions, registers, and functional units. It allows an instruction to proceed only when the needed resources and operands are ready, so hazards are avoided in a more systematic way.
Handling WAR and WAW
Modern out-of-order processors also need a way to let instructions finish out of order without exposing results in the wrong order. That is the role of the Reorder Buffer.