Part 5: Pipeline Hazards: Structural, Data Forwarding & Branch Prediction
Pipeline Hazards & Dynamic Mitigation
While ideal instruction pipelining achieves a CPI of 1.0, real-world processor execution is frequently disrupted by conditions that prevent the next instruction from executing in its designated clock cycle. These disruptive conflicts are designated as Pipeline Hazards. Hazards fall into three distinct architectural categories: Structural Hazards (hardware resource contention), Data Hazards (operand dependencies), and Control Hazards (branch trajectory uncertainty). In this article, we formulate the mechanisms of data forwarding (bypassing), load-use stalls, and dynamic 2-bit branch prediction.
1. Structural Hazards: Resource Conflicts
A Structural Hazard occurs when the processor hardware does not possess sufficient physical resources to support all possible combinations of instructions in the pipeline simultaneously.
Classic Example: If a processor uses a single, unified Von Neumann memory port for both instruction fetching (IF stage) and data loading/storing (MEM stage), a collision occurs whenever a LW or SW instruction accesses memory at the exact same cycle an upcoming instruction attempts to fetch its opcode.
Solution: Modern microprocessors resolve this by adopting a Modified Harvard Architecture with completely independent L1 Instruction Caches (I-Cache) and L1 Data Caches (D-Cache), allowing concurrent dual memory access without collisions.
2. Data Hazards: Read-After-Write (RAW) Dependencies
A Data Hazard arises when an instruction depends on the result of an earlier instruction that has not yet committed its value back into the register file:
SUB x4, x1, x5 # Needs x1 in ID cycle 3! (Stale value!)
If the pipeline simply waited for ADD to write back to register x1 during stage 5, the CPU would have to stall ("bubble") for two full clock cycles, degrading performance.
The Solution: Operand Forwarding (Bypassing)
The calculated ALU result for ADD is physically available at the output of the ALU at the end of the EX stage (cycle 3)—long before it is officially committed to the register file during WB (cycle 5).
A dedicated Forwarding Unit routes the output of the EX/MEM or MEM/WB pipeline registers directly back into the ALU multiplexer inputs for the subsequent instruction:
if (EX/MEM.RegWrite && (EX/MEM.RegisterRd != 0) && (EX/MEM.RegisterRd == ID/EX.RegisterRs1))
ForwardA = 2'b10; // Select forwarded ALU result directly
The Load-Use Exception (Mandatory 1-Cycle Stall)
When an instruction immediately follows a Load Word (LW) instruction that supplies its operand, forwarding alone cannot prevent a stall because data from memory is not available until the end of the MEM stage (cycle 4), while the dependent instruction needs it at the start of EX (cycle 4). The Hazard Detection Unit detects this condition and automatically injects a 1-cycle pipeline bubble (a no-op) while preserving the PC and IF/ID registers.
3. Control Hazards: Branch Uncertainty & Prediction
A Control Hazard occurs when the CPU encounters a conditional branch (e.g. BEQ, BNE). In the basic 5-stage pipeline, the branch decision and target address are not resolved until stage 3 (EX) or stage 4 (MEM). By that time, 2 to 3 subsequent instructions have already entered the pipeline. If the branch is taken, these speculative instructions must be flushed (cleared to zeros), wasting cycles.
Dynamic 2-Bit Saturating Counter Branch Predictor
Rather than stalling the pipeline, modern processors dynamically predict branch outcomes using a 2-Bit Saturating Counter state machine:
00
Strongly Not-Taken
01
Weakly Not-Taken
10
Weakly Taken
11
Strongly Taken
Unlike a 1-bit predictor (which mispredicts twice on every loop termination), a 2-bit counter requires two consecutive unexpected outcomes to change its prediction. Modern superscalar CPUs pair this with Branch Target Buffers (BTB) and neural TAGE predictors, achieving branch prediction accuracy exceeding 98%.
Related reading
Part 10: Multicore Systems: SMP, NUMA Architecture & Amdahl's Law Scaling
A study of multicore scalability, exploring Symmetric Multiprocessing (SMP), Non-Uniform Memory Access (NUMA), Amdahl's law, and on-chip mesh Networks-on-Chip.
By Md. Harun-Or-Roshid
Part 9: SIMD Vector Processors & GPU Massively Parallel Compute Engines
A study of data-level parallelism, exploring Flynn's taxonomy, AVX-512 vector lane striping, GPU Streaming Multiprocessors, warps, and SIMT execution engines.
By Md. Harun-Or-Roshid
Part 8: Instruction Set Architecture: CISC vs RISC & The Open RISC-V Standard
A masterclass in computer instruction set architectures, comparing x86 CISC with ARM, evaluating the Iron Law of CPU performance, and exploring modular open RISC-V.
By Md. Harun-Or-Roshid
Part 7: Virtual Memory: Multi-Level Paging, Page Faults & TLB Translation
A comprehensive analysis of virtual memory architecture, multi-level hierarchical page tables, hardware MMU address translation, and TLB HugePages acceleration.
By Md. Harun-Or-Roshid