18 / 24 · Concept
Dependencies, resource hazards, and forwarding
Compare stalls and forwarding when an operation needs an earlier result.
Lessons are free to read. Enroll to save your learning progress.
Overlap requires more than preserving order
Independent stream calculations do not read earlier results, so transactions can overlap safely. A register-file operator may instead need a preceding operation's result. Reading a register before an older write becomes available creates a read-after-write data hazard. The arithmetic can be correct while its operand was sampled too early.
Start with R1=4. Let I0 perform R1←R1+3 and I1 perform R2←R1×2. In this example, I0 captures operand 4 at edge 0, computes 7 during the following cycle, and writes R1 at edge 1. I1 sampling R1 at edge 1 may see old value 4, producing R2=8. Sequential execution requires R2=14. Specify same-edge register-file read/write behavior explicitly.
| Remedy | Operand seen by I1 | Requirement |
|---|---|---|
| Read old R1 | 4 | Incorrect here |
| Stall until edge 2 | 7 | Preserve operation and companion fields |
| Forward execution result | 7 just before edge 1 | Result available and path meets timing |
Forwarding selects a computed result before it reaches architectural storage. Matching destination numbers is insufficient: the producer must be valid, actually write the register, and have a ready result. With multiple matching producers, choose the youngest older operation. Never forward a bubble or flushed operation.
A load whose response has not arrived cannot be fixed by forwarding unavailable data. Stall the consumer while preserving opcode, source identifiers, and tag. Decide whether other independent stages may continue.
Structural hazards arise when two stages need one memory port at the same time. Arbitration or extra resources are needed even without data dependence. Branches introduce control hazards requiring cancellation of wrong-path work. Analyze what each operation waits for and which state must hold. Our capstone remains an independent stream; passing it is not evidence of CPU dependency handling.
Try it yourself
With R1=4, I0 adds three and I1 doubles the result. Compare I1's result from old storage and correct forwarding. What if I0 is a load whose data is not yet available?
Read the explanation
Reading old 4 gives 8; forwarding 7 gives 14. An unavailable load result requires a consumer stall with its operation and tag preserved. A destination match cannot justify forwarding unfinished data.