Structural, data and control hazards
Why a pipeline cannot always start an instruction every cycle: structural hazards (a shared resource), data hazards (RAW, and WAR and WAW), control hazards (branches), how many stall cycles each costs with and without forwarding, and how interlocks and compilers deal with them.
Why it exists
The pipeline assumes that a new instruction can start every cycle and that each instruction can do its work in its stage without waiting. Real programs break that assumption in three ways: two instructions want the same piece of hardware in the same cycle, an instruction needs a result that an earlier instruction has not produced yet, or the next instruction to fetch is not known because a branch has not been decided. These situations are hazards. A hazard forces the pipeline to stall, so CPI rises above 1, as the performance page computes. GATE asks you to classify hazards, count stall cycles for a given instruction sequence, and say what each remedy does.
Prerequisites
You need the five stages and the space-time diagram of instruction pipelining.
Precise definitions
Hazard. A situation in which the next instruction cannot execute in its designated clock cycle without producing a wrong result or conflicting for hardware.
Structural hazard. Two instructions need the same hardware resource in the same cycle. The standard case: a single memory used for both instructions and data. A load or store in MEM and the fetch of a later instruction in IF both need the memory in the same cycle. Other cases: a single register-file port, a functional unit that is not pipelined (a slow divider). Remedies: stall one of them; or duplicate the resource (separate instruction and data memories or caches, a register file with two read ports and one write port); or pipeline the unit.
Data hazard. An instruction depends on the data of an earlier one still in the pipeline. Three kinds, named by the order of the accesses to the same register:
- RAW (read after write, true dependence). The later instruction reads a register that the earlier one writes. Example:
add r3,r1,r4afterlw r1,0(r2). This is the hazard that matters in the simple in-order pipeline. - WAR (write after read, anti-dependence). The later instruction writes a register that the earlier one reads; a wrong order would make the earlier one read the new value.
- WAW (write after write, output dependence). Both write the same register; a wrong order would leave the older value.
In the five-stage in-order pipeline registers are read early (ID) and written late (WB), always in program order, so WAR and WAW cannot go wrong. They appear when instructions can finish out of order or write in different stages (longer floating-point pipelines, out-of-order machines) and are removed there by register renaming.
Control hazard. The address of the next instruction is not known until a branch (or jump) has been resolved, so instructions fetched meanwhile may be the wrong ones. See forwarding, stalls and branch prediction. The cost of a branch is its branch penalty: the number of cycles lost, equal to the position of the stage in which the branch is resolved (counting IF as 1) minus 1, that is the number of wrongly fetched instructions (resolved in ID: 1; in EX: 2; in MEM: 3).
Stall (bubble, interlock). The hardware hazard detection unit compares the register numbers of the instruction in ID with the destination registers of those further along. When it finds a hazard it freezes the PC and the IF/ID register and sends a bubble (a no-operation) down the pipeline. Alternatively the compiler avoids hazards by reordering independent instructions into the gaps or by inserting no-operations; this needs no hardware detection but ties the code to one pipeline.
Stalls caused by a RAW hazard. Assume the register file is written in the first half of a clock cycle and read in the second half (so a value written in WB can be read in the same cycle's ID). The distance between producer and consumer is the number of instructions from the producer to the consumer (adjacent instructions have ). Without forwarding, the consumer must read in an ID cycle at or after the producer's WB:
| distance | 1 | 2 | 3 or more |
|---|---|---|---|
| stalls without forwarding | 2 | 1 | 0 |
If the register file cannot be written and read in the same cycle, every entry rises by one (3, 2, 1, 0). With forwarding (next page) the ALU-to-ALU case needs no stall at all and a load followed immediately by its use needs one.
How it works
The first animation runs five dependent instructions with no forwarding. Each stall (amber) is a cycle where the dependent instruction sits in ID waiting for its source to be written back; the instructions behind it wait too (grey). The result is 15 cycles instead of the ideal 9.
Data hazards without forwarding: start
Pipeline simulated, not typed| cycle | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| lw r1,0(r2) | |||||||||||||||
| add r3,r1,r4 | |||||||||||||||
| sub r5,r3,r6 | |||||||||||||||
| sw r5,0(r7) | |||||||||||||||
| or r8,r9,r10 |
Step 0
Five instructions in which each uses the result of an earlier one: add reads r1 (loaded by lw), sub reads r3 (from add), sw reads r5 (from sub). With no forwarding a result can only be used after it has been written to the register file in WB, so a dependent instruction waits in ID. The register file is written in the first half of a cycle and read in the second half, so a consumer may read in the same cycle as the producer's WB.
The second animation shows a structural hazard. The machine has one memory for instructions and data. When the load reaches MEM in cycle 4 the memory is busy, so the instruction that would be fetched in that cycle must wait. The amber cell is the delayed fetch; everything behind it shifts by one cycle.
A structural hazard: one memory port: start
Pipeline simulated, not typed| cycle | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
|---|---|---|---|---|---|---|---|---|---|---|
| lw r1,0(r2) | ||||||||||
| add r3,r4,r5 | ||||||||||
| add r6,r7,r8 | ||||||||||
| add r9,r10,r11 | ||||||||||
| add r12,r13,r14 |
Step 0
A load followed by four independent adds, on a machine with ONE memory used for both instructions and data. When the load is in MEM (cycle 4), the memory is busy with its data access, so the instruction that would be fetched in cycle 4 cannot be: the fetch is delayed one cycle, leaving a bubble.
Worked examples
EX 1Find the dependences
EasyIn lw r1,0(r2), add r3,r1,r4, sub r5,r3,r6, sw r5,0(r7), or r8,r9,r10: add reads r1 written by lw (RAW, ); sub reads r3 written by add (RAW, ); sw reads r5 written by sub (RAW, ); or uses and writes registers nobody else touches, so it is independent. There are three RAW hazards, each at distance 1.
EX 2Count the stalls, with and without forwarding
MediumThe same five instructions. Each of the three adjacent dependent pairs stalls 2 cycles without forwarding (distance 1). With forwarding only the load-use pair stalls, by 1 cycle. A program computes both, and the stall count for any distance.
#include <stdio.h>
/* five-stage pipeline: IF ID EX MEM WB, one instruction per stage per cycle.
The register file is written in the first half of WB and read in the second half of ID. */
struct ins { const char *text; int is_load; int dst; int src1, src2; };
static int total_cycles(const struct ins *p, int n, int forwarding, int *stalls) {
int a[16][5]; /* a[i][s]: first cycle of instruction i in stage s */
for (int i = 0; i < n; i++) {
a[i][0] = i == 0 ? 1 : a[i - 1][1];
a[i][1] = a[i][0] + 1;
if (i > 0 && a[i - 1][2] > a[i][1]) a[i][1] = a[i - 1][2];
int ex = a[i][1] + 1;
if (i > 0 && a[i - 1][3] > ex) ex = a[i - 1][3];
int natural = ex;
for (int k = 0; k < i; k++) { /* every older writer of a source register (the newest one is the binding one) */
if (p[k].dst == 0) continue;
if (p[k].dst != p[i].src1 && p[k].dst != p[i].src2) continue;
int need = forwarding ? a[k][p[k].is_load ? 3 : 2] + 1 : a[k][4] + 1;
if (need > ex) ex = need;
}
*stalls += ex - natural;
a[i][2] = ex;
a[i][3] = a[i][2] + 1;
if (i > 0 && a[i - 1][4] > a[i][3]) a[i][3] = a[i - 1][4];
a[i][4] = a[i][3] + 1;
}
return a[n - 1][4];
}
int main(void) {
/* lw r1,0(r2); add r3,r1,r4; sub r5,r3,r6; sw r5,0(r7); or r8,r9,r10 */
struct ins prog[5] = {
{"lw", 1, 1, 2, 0}, {"add", 0, 3, 1, 4}, {"sub", 0, 5, 3, 6}, {"sw", 0, 0, 5, 7}, {"or", 0, 8, 9, 10},
};
for (int fwd = 0; fwd <= 1; fwd++) {
int stalls = 0;
int cycles = total_cycles(prog, 5, fwd, &stalls);
printf("%s: stall cycles %d, total %d cycles (without stalls %d)\n", fwd ? "forwarding " : "no forwarding", stalls, cycles, 5 + 5 - 1);
}
/* producer, then d-1 independent instructions, then the consumer */
printf("distance d: 1 2 3 4\n");
for (int mode = 0; mode < 3; mode++) {
printf("%-18s", mode == 0 ? "no forwarding" : mode == 1 ? "forwarding, ALU" : "forwarding, load");
for (int d = 1; d <= 4; d++) {
struct ins q[8];
int n = 0;
q[n++] = (struct ins){"p", mode == 2, 1, 20, 21};
for (int k = 0; k < d - 1; k++) q[n++] = (struct ins){"x", 0, 10 + k, 22, 23};
q[n++] = (struct ins){"c", 0, 2, 1, 24};
int stalls = 0;
total_cycles(q, n, mode != 0, &stalls);
printf("%d ", stalls);
}
printf("\n");
}
return 0;
}no forwarding: stall cycles 6, total 15 cycles (without stalls 9)
forwarding : stall cycles 1, total 10 cycles (without stalls 9)
distance d: 1 2 3 4
no forwarding 2 1 0 0
forwarding, ALU 0 0 0 0
forwarding, load 1 0 0 0 Reading it. Without forwarding: 3 pairs 2 stalls , so cycles (the first animation). With forwarding: only the load-use pair, 1 stall, so 10 cycles. The table is the rule from the definitions: 2, 1, 0 stalls for distance 1, 2, 3 without forwarding; a loaded value used by the very next instruction costs 1 stall even with forwarding.
EX 3A chain of four adds
Mediumadd r1,r8,r9; add r2,r1,r10; add r3,r2,r1; add r4,r3,r11. Without forwarding: the second needs r1 from the first (, 2 stalls). The third needs r2 (, 2 stalls) and r1 (, which would stall 1 but the 2 stalls already given cover it, since the binding dependence is the nearest). The fourth needs r3 (, 2 stalls). Total stalls 6, so cycles. With forwarding there are no stalls: cycles. When one instruction has two hazards, the latest-available source decides, so apply the largest of the stalls, not their sum.
EX 4A structural hazard with one memory
MediumA machine fetches instructions and data from one single-ported memory. A load is followed by four independent instructions (second animation). In cycle 4 the load is in MEM, so the instruction that would be fetched in cycle 4 waits one cycle: total cycles instead of 9. In a program where a fraction of the instructions are loads or stores (and there are always enough instructions after each), every such instruction costs one lost fetch cycle: stalls per instruction and CPI . With , CPI . Giving the machine separate instruction and data memories removes the hazard and the cost.
EX 5Classify the hazards
GATE levelI1: add r1,r2,r3; I2: sub r4,r1,r5; I3: or r1,r6,r7; I4: and r8,r4,r1.
- I2 reads r1 written by I1: RAW.
- I3 writes r1 which I2 reads: WAR (I2 must read the old value; harmless in an in-order pipeline because I2 reads in ID, long before I3 writes in WB).
- I3 writes r1 which I1 also wrote: WAW (harmless in order; I3's value must be the one left in r1).
- I4 reads r4 (written by I2, RAW) and r1 (the value written by I3, RAW, not the one from I1).
In the five-stage in-order pipeline only the RAW hazards cause stalls. Which writer a reader depends on is the nearest earlier one in program order.
Cheat box
Cheat box
- Structural: shared hardware (one memory port). Data: RAW (the one that stalls in-order), WAR, WAW. Control: branches.
- RAW without forwarding (write first half, read second half): distance 1, 2, 3 gives 2, 1, 0 stalls. If no same-cycle read/write: 3, 2, 1, 0.
- With forwarding: ALU to ALU: 0 stalls. Load then immediate use: 1 stall.
- Several hazards on one instruction: take the largest stall, not the sum.
- Branch penalty (stage in which it is resolved) stages: ID 1, EX 2, MEM 3.
- Total cycles stall cycles. CPI stalls per instruction.
- Remedies: stall (interlock), forward, reorder in the compiler, duplicate hardware, predict branches.
Traps and GATE patterns
Connections
Builds on
Across subjects
No cross-subject links yet.
Hazards are why the speedup of the pipeline falls below the stage count, in the CPI arithmetic of pipeline performance. Their cures, forwarding, compiler scheduling and branch prediction, are the subject of forwarding, stalls and branch prediction. An interrupt arriving in a pipeline must leave the instructions before it complete and those after it not started (a precise interrupt), which is hard precisely because several instructions are in flight. A regular ISA with few memory-accessing instructions and few operands keeps hazards simple.
PYQs
14 previous year questions from your book. I re-solved each one myself (11 by running or simulating, 3 by reasoning only); the book's key is shown next to my answer. All PYQs
Which one of the following dependencies among the register operands of different instructions can cause a data hazard in a pipelined processor?
- (a)Read-after-read
- (b)Read-after-write
- (c)Write-after-read
- (d)Write-after-write
The EX stage of a pipelined processor performs the memory read operations for LOAD instructions, and the operations for the arithmetic and logic instructions. Let tEX denote the time taken by the EX stage to perform the operation for an instruction. For each instruction type, the values of tEX and M (the number of instructions of that type in a sequence of 100 instructions for a program P), are given in the table below. The duration of the pipeline clock cycle is 1 nanosecond. Assume that the latch time for the interstage buffers in the pipeline is negligible. When program P is executed, the number of clock cycles for which the pipeline is stalled due to structural hazards in the EX-stage is . (answer in integer).
An instruction format has the following structure: Instruction Number: Opcode destination reg, source reg-1, source reg-2 Consider the following sequence of instructions to be executed in a pipelined processor: I1 : DIVR3,R1,R2 I2 : SUB R5,R3,R4 I3 : ADDR3,R5,R6 I4: MUL R7,R3,R8 Which of the following statements is/are TRUE?
- (a)There is a RAW dependency on R3 between I1 and I2
- (b)There is a WAR dependency on R3 between I1 and I3
- (c)There is a RAW dependency on R3 between I2 and I3
- (d)There is a WAW dependency on R3 between I3 and I4
A non-pipelined instruction execution unit operating at 2 GHz takes an average of 6 cycles to execute an instruction of a program P. The unit is then redesigned to operate on a 5-stage pipeline at 2 GHz. Assume that the ideal throughput of the pipelined unit is 1 instruction per cycle. In the execution of program P, 20% instructions incur an average of 2 cycles stall due to data hazards and 20% instructions incur an average of 3 cycles stall due to control hazards. The speedup (rounded off to one decimal place) obtained by the pipelined design over the non-pipelined design is
Consider a pipelined processor with 5 stages, Instruction Fetch (IF), Instruction Decode (ID), Execute (EX), Memory Access (MEM), and Write Back (WB). Each stage of the pipeline, except the EX-stage, takes one cycle. Assume that the ID stage merely decodes the instruction and the register read is performed in the EX-stage. The EX-stage takes one cycle for ADD instruction and two cycles for MUL instruction. Ignore pipeline register latencies. Consider the following sequence of 8 instructions: ADD, MUL, ADD, MUL, ADD, MUL, ADD, MUL Assume that every MUL instruction is data- dependent on the ADD instruction just before it and every ADD instruction (except the first ADD) is data-dependent on the MUL instruction just before it. The speedup is defined as follows: Speedup = Execution time without operand forwarding Execution time with operand forwarding The Speedup achieved in executing the given instruction sequence on the pipelined processor (rounded to 2 decimal places) is . and 50% of the branch instructions cause stalls of 2 cycles each. Assume that there are no stalls associated with the execution of ALU instructions. For this program, the speedup achieved by the pipelined processor over the non-pipelined processor (round off to 2 decimal places) is .
Consider a non-pipelined processor operating at 2.5 GHz. It takes 5 clock cycles to complete an instruction. You are going to make a 5-stage pipeline out of this processor. Overheads associated with pipelining force you to operate the pipelined processor at 2 GHz. In a given program, assume that 30% are memory instructions, 60% are ALU instructions and the rest are branch instructions. 5% of the memory instructions cause stalls of 50 clock cycles each due to cache misses
Consider the sequence of machine instructions given below In the above sequence, R0 to R8 are general purpose registers. In the instructions shown, the first register stores the result of the operation performed on the second and the third registers. This sequence of instructions is to be executed in a pipelined instruction processor with the following 4 stages: (1) Instruction Fetch and Decode (IF) (2) Operand Fetch (OF) (3) Perform Operation (PO) and (4) Write back the result (WB). The IF, OF and WB stages take 1 clock cycle each for any instruction. The PO stage takes 1 clock cycle for ADD or SUB instruction, 3 clock cycles for MUL instruction and 5 clock cycles for DIV instruction. The pipelined processor uses operand forwarding from the PO stage to the OF stage. The number of clock cycles taken for the execution of the above sequence of instructions is .
Consider the following code sequence having five instructions from I1 to I5. Each of these instructions has the following format. OP Ri, Rj, Rk Where operation OP is performed on contents of registers Rj and Rk and the result is stored in register MUL R5, R0, R1 DIV R6, R2, R3 ADD R7, R5, R6 SUB R8, R7, R4 Computer Organization and Architecture Ri. I1 : ADD R1, R2, R3 I2 : MUL R7, R1, R3 I3 : SUB R4, R1, R5 I4 : ADD R3, R2, R4 I5: MUL R7, R8, R9 Consider the following three statements. S1: There is an anti-dependence between instructions I2 and I5 S2: There is an anti-dependence between instructions I2 and I4 S3: Within an instruction pipeline an anti- dependence always creates one or more stalls Which one of the above statements is/are correct?
- (a)Only S1 is true
- (b)Only S2 is true
- (c)Only S1 and S3 are true
- (d)Only S2 and S3 are true
An instruction pipeline has five stages, namely, instruction fetch (IF), instruction decode and register fetch (ID/RF), instruction execution (EX), memory access (MEM), and register writeback (WB) with stage latencies 1 ns, 2.2 ns, 2 ns, 1 ns, and 0.75 ns, respectively (ns stands for nanoseconds). To gain in terms of performance, the designers have decided to split the ID/RF stage into three stages (ID, RF1, RF2) each of latency 2.2/3 ns. Also, the EX stage is split into two stages (EX1, EX2) each of latency 1 ns. The new design has a total of eight pipeline stages. A program has 20% branch instructions which execute in the EX stage and produce the next instruction pointer at the end of the EX stage in the old design and at the end of the EX2 stage in the new design. The IF stage stalls after fetching a branch until the next instruction pointer is computed. All instructions other than the branch instruction have an average CPI of one in both the designs. The execution times of this program on the old and the new design are P and Q nanoseconds, respectively. The value of P/Q is .
Consider a 6-stage instruction pipeline, where all stages are perfectly balanced. Assume that there is no cycle-time overhead of pipelining. When an application is executing on this 6-stage pipeline, the speedup achieved with respect to non-pipelined execution is 25% if the instructions incur 2 pipeline stall cycles is .
Register renaming is done in pipelined processors
- (a)as an alternative to register allocation at compile time
- (b)for efficient access to function parameters and local variables
- (c)to handle certain kinds of hazards
- (d)as part of address translation
Which of the following are NOT true in a pipelined processor? 1. Bypassing can handle all RAW hazards. 2. Register renaming can eliminate all register carried WAR hazards. 3. Control hazard penalties can be eliminated by dynamic branch prediction.
- (a)1 and 2 only
- (b)1 and 3 only
- (c)2 and 3 only
- (d)1, 2 and 3
A pipelined processor uses a 4-stage instruction pipeline with the following stages: Instruction fetch (IF), Instruction decode (ID), Execute (EX) and Writeback (WB). The arithmetic operations as well as the load and store operations are carried out in the EX stage. The sequence of instructions corresponding to the statement X=(S-R*(P+Q))/T is given below. The values of variables P,Q,R,S and T are available in the registers R0,R1,R2,R3 and R4 respectively, before the execution of the instruction sequence. ADD R5,R0,R1 ;R5←R0 + R1 MUL R6,R2,R5 ;R6←R2 * R5 SUB R5,R3,R6 ;R5←R3 -R6 DIV R6,R5,R4 ;R6←R5/R4 STORE R6,X ;X←R6 The IF, ID and WB stages take 1 clock cycle each. The EX stage takes 1 clock cycle each for the ADD, SUB and STORE operations, and 3 clock cycles each for MUL and DIV operations. Operand forwarding from the EX stage to the ID stage is used. The number of Read- After-Write (RAW) dependencies, Write-After- Read( WAR) dependencies, and Write After-Write (WAW) dependencies in the sequence of instructions are, respectively,
- (a)2,2,4
- (b)3,2,3
- (c)4,2,2
- (d)3,3,2
Following table indicates the latencies of operations between the instruction producing the result and instruction using the result. Instruction producing the result Instruction using the result Latency ALU Operation ALU Operation 2 ALU Operation Store 2 Load ALU Operation 1 Load Store 0 Consider the following code segment: Load R1, Loc 1; Load R1 from memory location Loc1 Load R2, Loc 2; Load R2 from memory location Loc 2 Add R1, R2, R1; Add R1 and R2 and save result in R1 Dec R2; Decrement R2 Dec R1; Decrement R1 Mpy R1, R2, R3; Multiply R1 and R2 and save result in R3 Store R3, Loc 3; Store R3 in memory location Loc 3 What is the number of cycles needed to execute the above code segment assuming each instruction takes one cycle to execute?
- (a)7
- (b)10
- (c)13
- (d)14
Self-check
Question 1
Without forwarding (write first half, read second half), how many stall cycles does an instruction incur if it uses the result of the instruction two before it?
Show answerHide
Distance 2: one stall.
Question 2
Four independent instructions and a fifth that uses the result of the first. How many stalls without forwarding?
Show answerHide
The fifth is at distance 4 from the producer: no stall.
Question 3
A load followed by an instruction that uses the loaded register, with full forwarding: stalls?
Show answerHide
One. The data is available only at the end of MEM.
Question 4
A program has 25% loads and stores and a single memory port, with enough instructions after each. What is the CPI from this structural hazard alone?
Show answerHide
.
Revision card
One-screen revision
- Three hazards: structural (resource), data (RAW, WAR, WAW), control (branch).
- RAW, no forwarding: stalls 2, 1, 0 at distance 1, 2, 3; with forwarding 0, and load-use 1.
- Largest stall wins, not the sum. Total stalls.
- Branch penalty resolving stage .
- Fixes: interlock, forwarding, reordering, more hardware, prediction.
References
- ·Hennessy and Patterson, Computer Organization and Design, Chapter 4 The Processor (pipeline hazards: structural, data, control)
- ·Hamacher, Vranesic, Zaky, Computer Organization, 5th ed., the Pipelining chapter (data hazards, instruction hazards)
- ·Stallings, Computer Organization and Architecture, Instruction pipelining chapter (pipeline hazards)
Verification
The stall counts, the totals of 15 and 10 cycles, the table of stalls by distance and the 14-cycle chain are produced by the C program on this page (npm run verify:c) and by scripts/gen-coa-hazard-traces.py. That schedule is compared in scripts/enum-checks/coa_hazard.py with an independent cycle-driven machine that has its own hazard-detection logic, on 6000 random programs and configurations (data, structural and control hazards together), and tests/coa-hazard-traces.test.ts rechecks, for every diagram, that each stage starts at exactly the earliest cycle the rules allow. All numbers assume the stated model: five stages, in order, register file written in the first half and read in the second half of a cycle; other conventions shift the counts by the amounts stated on the page. Textbook chapter titles are from memory. SECOND PASS (2026-11-02, done by the assistant, not a human check): every Self-check question was solved before the printed answer was read and all agreed; the definitions, worked examples, cheat box and traps were read claim by claim and the numbers re-derived by hand (long C programs were not re-read line by line: they are compiled and compared by npm run verify:c, and their printed outputs were checked against the prose). The definition of the branch penalty was reworded (the position of the resolving stage minus 1). Status raised to self-checked; verified needs a textbook or human check.
last verified: never
My notes (saved in this browser)