Exercises — Pipeline hazards — structural, data (RAW - WAR - WAW), control
Throughout, we reuse the parent's 5-stage pipeline: IF (fetch), ID (decode + read registers), EX (execute in the ALU), MEM (memory access), WB (write result back to a register). We also reuse the parent's symbols:
Level 1 — Recognition
Goal: name the hazard family and the mechanism, no maths.
L1.1
I1: LW R1, 0(R2) # load: R1 <- memory[R2]
I2: ADD R3, R1, R4 # uses R1Which hazard family is this, and can plain forwarding remove it completely?
Recall Solution
RAW data hazard (I2 reads R1 which I1 must write first). It is the special load-use case. Plain forwarding cannot fully remove it: a load's value is only ready at the end of MEM (cycle 4), but the dependent ADD wants it in EX (also cycle 4). There is no earlier stage to forward from, so you need one bubble, then forward. See Forwarding and bypassing.
L1.2
Two independent instructions both need the single unified memory in the same cycle — one for IF, one for MEM. Name the family and the by-design cure.
Recall Solution
Structural hazard (resource conflict, not a value conflict). By-design cure: split the memory into a separate I-cache and D-cache (Harvard style) so IF and MEM never fight.
L1.3
Match each label to its dependence type: RAW, WAR, WAW.
Recall Solution
- RAW = Read After Write = true dependence (real data flow).
- WAR = Write After Read = anti-dependence (a name hazard).
- WAW = Write After Write = output dependence (a name hazard). Only RAW is a true dependence; WAR/WAW come from reusing register names and vanish with Register renaming.
Level 2 — Application
Goal: use the parent's formulas on concrete numbers.
L2.1
A program has branches, misprediction rate , branch penalty cycles. Ideal CPI is 1. Find the actual CPI.
Recall Solution
Use . Why this form? Only branches () can stall; only mispredicted ones () actually do; each costs .
L2.2
A 5-stage pipeline has an average stall of cycles per instruction. What is the speedup over a single-cycle machine?
Recall Solution
Use . Why: single-cycle spends stage-times per instruction; the pipeline spends cycles.
L2.3
Same , , but you install a good predictor that drops from to . New CPI?
Recall Solution
The branch stall term fell from to — see Branch prediction (static vs dynamic) for why dynamic prediction earns this.
Level 3 — Analysis
Goal: reason about cycle grids and count bubbles.
L3.1
Draw the cycle grid and count stalls (forwarding enabled) for:
I1: ADD R1, R2, R3
I2: SUB R4, R1, R5Recall Solution

L3.2
Now the producer is a load:
I1: LW R1, 0(R2)
I2: SUB R4, R1, R5With forwarding, how many bubbles?
Recall Solution

L3.3
A branch resolves in EX (the 3rd stage). With a predict-not-taken scheme, how many instructions are flushed on a taken branch, and what is ?
Recall Solution
With no prediction help, IF keeps fetching the fall-through instructions in c2 and c3 while the branch is in ID and EX. When the branch resolves taken in EX (c3), the 2 instructions fetched behind it (in IF at c2, c3) are wrong and get flushed. So cycles. Correctly predicted (not-taken and it is not-taken): . The penalty only bites on the outcome the predictor missed.
Level 4 — Synthesis
Goal: combine multiple hazard sources into one CPI.
L4.1
A workload runs on the 5-stage pipeline with all three stall sources:
- Data stalls: 30% of instructions are loads; half of those ( of all) are immediately load-used → 1 bubble each.
- Control stalls: , , .
- Structural stalls: none (split caches).
Compute the total CPI.
Recall Solution
Add each stall contribution to the ideal CPI of 1.
- Data: .
- Control: .
- Structural: .
L4.2
For the L4.1 machine, what speedup does it get over a single-cycle machine ()? Then: which single fix helps more — eliminating the load-use stalls, or halving ?
Recall Solution
, so .
Eliminate load-use (e.g. compiler scheduling): remove → CPI . Halve to : control term → CPI . The load-use fix drops CPI to 1.06 vs 1.18 — removing load-use stalls helps far more here, because . Attack the biggest stall term first (this is Amdahl's Law thinking).
Level 5 — Mastery
Goal: reason where the simple in-order model breaks and why renaming/OoO is needed.
L5.1
I1: MUL R1, R2, R3 # multi-cycle EX, writes R1 LATE
I2: ADD R1, R4, R5 # single-cycle EX, writes R1 EARLYIn a machine where MUL's WB can arrive after ADD's WB, name the hazard, explain why our textbook in-order pipeline is immune but this machine is not, and give the fix.
Recall Solution
WAW (Write After Write / output dependence). The architectural R1 must end up holding I2's (later, in program order) value, but if MUL's WB lands after ADD's, R1 is left with the stale MUL result. Why the simple pipeline is immune: all instructions write in the same stage (WB) and flow in order, so writes retire in program order automatically. WAW only becomes real when write timing can be reordered (variable-latency EX or out-of-order retire). See Out-of-order execution and Tomasulo. Fix: Register renaming — give each write a fresh physical register, so I1 and I2 no longer share the name R1. WAW and WAR are name dependences; renaming dissolves them. Only RAW (true data flow) survives.
L5.2
Explain why WAR hazards cannot occur in the plain in-order 5-stage pipeline, using the exact stage where reads and writes happen.
Recall Solution
A WAR hazard needs a later instruction to write a register before an earlier instruction reads it. In our pipeline, reads happen in ID (early) and writes happen in WB (late), and instructions enter in program order. So (earlier) reaches its ID before (later) reaches its WB. The read always precedes the write — WAR is structurally impossible here. It only appears once writes can happen early or instructions issue out of order.
L5.3 (capstone)
A design team proposes deepening the pipeline from to stages. This doubles clock frequency but the branch penalty grows from to (branch resolves later). Given , : does the deeper pipeline actually run the program faster? Assume performance and ignore other stalls.
Recall Solution
Compute CPI for each (control stalls only):
- 5-stage: .
- 10-stage: .
Performance . Let 5-stage frequency , so 10-stage . Yes, ~1.86× faster — the doubled frequency wins even though CPI rose slightly. But note the deeper pipeline only delivered , not the naive : the bigger branch penalty ate part of the frequency gain. That gap is exactly why deep pipelines demand excellent branch prediction. (See the CPI and performance equation.)
Recall Quick self-check clozes
RAW is the only true dependence; WAR and WAW are name dependences. The one RAW forwarding cannot fully remove ::: the load-use hazard (needs 1 bubble first). Formula linking branches to CPI ::: . Why WAR/WAW never happen in the plain in-order pipeline ::: reads are in ID (early), writes in WB (late), and instructions flow in program order. Fix that dissolves WAR and WAW ::: register renaming.
Return to the parent: 4.1.19 topic note.