Imagine a kitchen with five cooks but only one oven. However well you schedule the cooks, the moment two of them need to bake at the same instant, one must wait — not because of any dependency between their dishes, but because there simply isn't enough hardware to go around. That is a structural hazard: two instructions in the pipeline demand the same physical resource in the same cycle, and one of them has to stall.
Structural hazards are the most primitive of the three hazard families. Unlike a
The textbook structural hazard hides in the pipeline's use of memory. The IF stage reads an instruction from memory every cycle. The MEM stage reads or writes data for loads and stores. In steady state, every cycle has some instruction in IF and another in MEM — so if the machine has a single, unified memory with one access port, those two stages fight over it constantly.
Step through it: in cycle 4 the load lw is in MEM fetching its data while sub is
in IF fetching its instruction word — both reach for the one memory port. Something has to give. The
elegant fix is the Harvard split: give the machine a separate
instruction cache and data cache, each with its own port. Now IF talks
to the I-cache and MEM talks to the D-cache, and the collision vanishes. This is exactly why every real
CPU has split L1 caches.
Memory is the famous case, but the same pattern recurs whenever a resource is scarcer than the demand:
| Scarce resource | The collision | Cure |
|---|---|---|
| Single memory port | IF (instruction) vs MEM (data) in the same cycle | split I-cache + D-cache (Harvard) |
| One register-file write port | two instructions reaching WB together | add write ports; or write in the first half-cycle, read in the second |
| Non-pipelined multiplier / FPU | a multi-cycle unit can't accept a new op each cycle | pipeline the unit, duplicate it, or stall the issue |
The register-file trick is especially neat: the file is clocked so that writes happen in the first half of the cycle and reads in the second half. An instruction writing back and another reading the same register in the same cycle then see the new value — and the single physical port is time-shared, dodging both a structural and a data hazard at once.
Suppose we didn't split the caches. Then every load and store (say
The name comes from the Harvard Mark I (1944), a room-sized electromechanical calculator that stored its program on punched paper tape and its data in separate counters — instructions and data physically apart. The rival von Neumann model put both in one memory, which is what programmers see. Modern chips are sneaky hybrids: the programmer's model is von Neumann (one address space), but down at the L1 cache the hardware is Harvard — separate instruction and data caches — precisely to dodge this structural hazard. Two 80-year-old machines, still arguing inside your laptop.
It's easy to lump all three hazard types together, but the distinction is sharp and worth memorising. A data hazard is about a value not being ready; a control hazard is about not knowing which instruction is next; a structural hazard is about not having enough hardware. Two completely independent instructions — no shared registers, no branch — can still stall if they both need the one multiplier this cycle. If you catch yourself looking for a data dependence to explain a stall and there isn't one, ask whether they're fighting over a resource.