Pipelining & Hazards

the load-use hazard

Imagine asking a runner to fetch a book from a distant shelf, and the very next thing you do depends on what is in that book. No matter how fast the runner is, you cannot read the book before it arrives. The load-use hazard is exactly this awkward case: an instruction loads a value from memory, and the immediately following instruction tries to use it — but the value simply is not back from memory in time.

It is the one data hazard that forwarding alone cannot fully cure, and the reason is timing. In the five-stage pipeline, an ordinary arithmetic result is born at the end of EX, early enough to forward to the next instruction's EX. But a load's value does not exist until the end of MEM — one stage later. The next instruction reaches its own EX before the loaded value is available, so even the fastest forwarding wire has nothing to send yet. The hardware therefore must stall the using instruction by exactly one cycle; after that single bubble, forwarding from the MEM/WB register delivers the loaded value just in time.

This is why the load-use hazard matters in practice: loads are extremely common, so this one-cycle penalty would nag a program constantly if nothing were done. The classic remedy is scheduling — the compiler reorders code to slip an independent, unrelated instruction into the slot right after the load, so the cycle that would have been a bubble does useful work instead. Some older designs even exposed this as a 'load delay slot' the programmer had to fill. The load-use hazard is the textbook proof that forwarding has limits and that smart instruction ordering still earns real speed.

lw x1, 0(x2) then add x3, x1, x4 forces one stall, because x1 is not ready until after MEM. But reorder a harmless independent instruction into the gap — lw x1, 0(x2); or x6, x7, x8; add x3, x1, x4 — and the load delay is hidden, costing nothing.

The load-use hazard costs one stall because a load's value arrives a stage too late to forward; scheduling an independent instruction into the gap hides it.

Forwarding does not eliminate the load-use stall, it merely shrinks it to one cycle. Only an instruction that uses the load's result IMMEDIATELY pays; if even one independent instruction sits between the load and its use, there is no stall at all.

Also called
load-use stallload delay載入使用停頓載入延遲