Static scheduling is a technique where the compiler, not the hardware, determines the order in which instructions are executed to avoid pipeline hazards and improve performance.
In static scheduling, decisions about instruction reordering, pipeline hazard handling, and parallelism are made before runtime, during compile time.
The compiler schedules instructions so the pipeline can execute efficiently without needing complex hardware.
Static scheduling is used extensively in RISC architectures (such as MIPS, ARM, and RISC-V).
Hardware becomes simpler, and the compiler takes over hazard avoidance.
The compiler analyzes the program and identifies:
Then the compiler reorders instructions so that long-latency operations (like loads) have enough time to complete before their results are needed.
Suppose we have:
I1: LW R1, 0(R2)
I2: ADD R3, R1, R4 ; depends on R1
Without scheduling, ADD will stall waiting for the load result.
I1: LW R1, 0(R2)
I3: SUB R5, R6, R7 ; independent instruction placed here
I2: ADD R3, R1, R4
This eliminates the stall by inserting useful work.
The compiler may insert a NOP (No Operation):
LW R1, 0(R2)
NOP
ADD R3, R1, R4
This avoids hazard but wastes a cycle. Still, the decision is made statically, at compile time.
Compiler reorders or inserts NOPs.
Using delay slots (e.g., branch delay slots in MIPS):
BEQ R1, R2, Target
Instruction in delay slot (executed regardless)
As shown earlier.
These depend on out-of-order execution and are handled by dynamic scheduling, not static. Static pipelines do not allow out-of-order execution.
| Feature | Static Scheduling | Dynamic Scheduling |
|---|---|---|
| Who handles hazards? | Compiler | Hardware |
| Reordering | Before execution (compile-time) | During execution (runtime) |
| Hardware complexity | Low | High (requires Tomasulo, ROB) |
| Flexibility | Low | High |
| Used in | RISC | CISC, advanced CPUs |
| Handles WAW/WAR | No | Yes |
| Handles latency variations | Poor | Excellent |
✔ Simpler CPU hardware ✔ Lower power consumption ✔ Predictable performance ✔ Less pipeline complexity ✔ Compiler can optimize aggressively
✘ Compiler cannot predict runtime events (cache misses, branch behavior, etc.) ✘ Cannot handle dynamic latency variations ✘ Rarely ideal scheduling for all execution conditions ✘ May require extra NOPs if no independent instructions exist
Open this section to load past papers