Skip to content
Part IA Michaelmas Term

Pipeline Hazards

What is a hazard?

A hazard is any situation that prevents the next instruction from executing in the next clock cycle. Hazards arise because of dependencies between instructions that conflict with the pipelined execution model. There are two types covered in this course.

Data hazards

A data hazard occurs when one instruction needs a result that a previous instruction has not yet finished computing. The result is still somewhere in the pipeline, not yet written back to the register file.

Example

ADD R1, R2, R3    ; R1 = R2 + R3
SUB R4, R1, R5    ; R4 = R1 - R5  ← needs R1!

Pipeline view:

CycleADDSUB
1Fetch
2Decode (read R2, R3)Fetch
3Execute (ALU: R2+R3)Decode (read R1, R5) ← needs R1!
4Memory (idle)Execute
5Writeback (write R1)Memory

The SUB instruction decodes in cycle 3 and tries to read R1 from the register file. But the ADD instruction does not write R1 until cycle 5. Without intervention, SUB would read the old value of R1, producing a wrong result.

Solutions to data hazards

Stalling (inserting bubbles): Detect the hazard and insert one or more NOP (no-operation) cycles into the pipeline. This delays the dependent instruction until the result is available. Simple but wastes cycles.

Forwarding (also called bypassing): Route the ALU result directly from the Execute stage output to the next instruction’s Execute stage input, without waiting for writeback. In the example above, the ADD’s result is available at the end of cycle 3 (after the ALU). A forwarding path takes this value and feeds it directly into the SUB’s ALU input at the start of cycle 4, bypassing the register file entirely. This eliminates the stall for back-to-back ALU-to-ALU dependencies.

Forwarding cannot always eliminate stalls. A LOAD followed immediately by an instruction that uses the loaded value still requires one stall cycle (the “load-use hazard”), because the data is not available until after the Memory stage (end of cycle 4 for the LOAD), but the dependent instruction needs it at the start of cycle 4 (its Execute stage).

Control hazards

A control hazard occurs when the processor does not know which instruction to fetch next because a branch or jump has not yet been resolved.

Example

BEQZ R1, +10    ; if R1==0, next instruction is at PC+10
ADD R2, R3, R4  ; fetched before we know if branch is taken!

Pipeline view:

CycleBEQZNext?
1Fetch BEQZ
2Decode (read R1)Fetch PC+1 (speculative)
3Execute (test R1 for zero)???

The branch outcome is not known until the end of cycle 3 (after the ALU tests R1). But in cycle 2, while the BEQZ is in Decode, the next instruction (at PC+1) has already been fetched. If the branch is taken, that fetched instruction is wrong and must be discarded.

Solutions to control hazards

Predict not-taken: Always fetch PC+1 (the sequential next instruction). If the branch is not taken, everything is fine. If the branch is taken, flush the pipeline (convert the wrongly fetched instruction into a NOP) and start fetching from the branch target. This wastes one cycle per taken branch. Simplified: penalty = 1 cycle when branch is taken.

Branch delay slot: Always execute the instruction after the branch, regardless of whether the branch is taken. The compiler (or programmer) fills this slot with an instruction that is safe to execute regardless of the branch outcome (typically an independent instruction from before the branch, moved down). The MIPS architecture uses this approach. It avoids wasted cycles but complicates the ISA.

Branch prediction: Predict whether the branch will be taken based on history (e.g., a simple predictor might remember the last outcome for each branch instruction). Modern processors use sophisticated predictors. If the prediction is wrong, flush and restart.

This is a preview

The course slides state explicitly: “These issues will be addressed in the Computer Architecture course.” For the Digital Electronics Tripos, you are expected to understand hazards at a conceptual level:

  1. Know the two types: data hazards and control hazards.
  2. Be able to explain a simple example of each (like those above).
  3. Know the names of the solutions (stalling, forwarding, predict not-taken, branch delay slot) and in broad terms what they do.
  4. Understand why pipelining, despite hazards, is still the standard approach: the throughput gain vastly outweighs the occasional stall or flush.

You do NOT need to know:

  • Detailed forwarding logic (when to forward from EX/MEM vs MEM/WB).
  • Branch prediction algorithms (two-level, tournament, etc.).
  • Exact stall penalty calculations beyond the simple examples.
  • Write-after-read (WAR) or write-after-write (WAW) hazards (these arise in out-of-order execution, not covered).

Summary of processor architectures

ArchitectureCPIClock periodHardwareKey issue
Single-cycle1LongRedundant (3 adders, 2 memories)Wastes time on fast instructions
MulticycleVariable (~4)ShortReused (1 ALU, 1 memory)Complex FSM control
Pipelined~1 (after fill)Short (per stage)Pipeline registers addedHazards

See also: