Exercises — Out-of-order execution
5.3.2 · D4· Hardware › Advanced Microarchitecture › Out-of-order execution
Parent: 5.3.2 Out-of-order execution · Related: 5.1.01-Pipelining, 5.3.01-Superscalar-architecture, 5.3.03-Speculative-execution, 5.3.04-Register-renaming, 6.2.03-Branch-prediction, 7.1.01-Instruction-level-parallelism.
Shuru karne se pehle, ek chhota sa dictionary hai taaki koi bhi symbol use hone se pehle define ho jaye:
Level 1 — Recognition
L1.1 — Hazard pehchano
Har pair ke liye batao ki yeh RAW, WAR, WAW, ya none hai, aur kya register renaming isse hata sakti hai.
(a) I1: R1 = R2 + R3 I2: R4 = R1 + R5
(b) I1: R1 = R2 + R3 I2: R1 = R6 + R7
(c) I1: R4 = R1 + R5 I2: R1 = R6 + R7
(d) I1: R1 = R2 + R3 I2: R4 = R5 + R6
Recall Solution
- (a) RAW. I2,
R1read karta hai, jise I1 ne write kiya. Yeh ek true data dependency hai — value pehle actually produce honi chahiye. Renaming isse nahi hata sakti. - (b) WAW. Dono
R1write karte hain. Sirf I2 ki write bachni chahiye. Yeh false hai (naam ka reuse). Renaming isse hata deti hai: I2 ko ek fresh physical register do. - (c) WAR. I1,
R1read karta hai, phir I2R1overwrite karta hai. False — naamR1ka reuse hi ek conflict hai. Renaming isse hata deti hai. - (d) None. Alag-alag registers, poori tarah se independent, kisi bhi order mein execute ho sakte hain.
L1.2 — Lifecycle order karo
In chaar OoOE phases ko sahi order mein rakho aur mark karo ki kaun sa in program order chalta hai vs out of order: Execute, Fetch/Decode, Commit/Retire, Dispatch.
Recall Solution
- Fetch/Decode — in-order
- Dispatch (reservation stations mein) — in-order
- Execute — out of order (operands ready hone par fire karta hai)
- Commit/Retire — in-order (ROB ke through, taaki precise exceptions rahe)
Memory hook: in — in — OUT — in. Sirf beech wala execute stage scramble karne ke liye free hai; dono ends ordered rehte hain taaki programmer ko kabhi pata na chale.
Level 2 — Application
L2.1 — Parallelism expose karne ke liye rename karo
Is code ko fresh names T1, T2, … use karke rewrite karo taaki saari false dependencies khatam ho jayein. Phir batao ki ab kaun si instructions parallel mein execute ho sakti hain.
I1: R1 = R2 + R3
I2: R4 = R1 * R6 ; uses R1
I3: R1 = R7 - R8 ; reuses R1
I4: R9 = R1 + R5 ; uses new R1
Recall Solution
Har architectural register ki har write ko ek naye physical naam se map karo, aur har read ko sabse recent prior write ke physical naam se:
I1: T1 = R2 + R3
I2: R4 = T1 * R6 ; RAW on T1 -> must wait for I1
I3: T2 = R7 - R8 ; independent of everything above
I4: R9 = T2 + R5 ; RAW on T2 -> must wait for I3
- I1/I2 mein
R1T1ban gaya; I3/I4 meinR1T2ban gaya. I1 aur I3 ke beech WAW (aur I2 aur I3 ke beech WAR) khatam ho gaye. - Do independent chains bachi hain: {I1 → I2} aur {I3 → I4}. Woh parallel mein chalte hain.
- Unlimited ports aur 1-cycle ops ke saath: I1 aur I3 cycle 1 mein fire karte hain; I2 aur I4 cycle 2 mein fire karte hain. Poora block 2 cycles mein khatam hota hai 4 ki jagah.
L2.2 — Ready condition
Ek reservation station I: R5 = src1 + src2 hold kar raha hai, jahan src1 ko producer P8 (abhi done nahi) se aane wala tagged kiya gaya hai aur src2 = 12 already ek value hai. Common Data Bus (CDB) par (tag=P8, value=7) appear hota hai. Kya hota hai, aur I kis cycle mein fire kar sakta hai agar broadcast cycle 4 ke end mein land ho?
Recall Solution
Station CDB snoop karta hai, apna waiting tag P8 match hota dekh value capture kar leta hai:
Ab .
Dono operands cycle 4 ke end mein available hain ⇒ I agli cycle = cycle 5 mein fire karta hai, compute karta hai.
Level 3 — Analysis
L3.1 — Dono timelines banao
Neeche diye code ke liye, in-order aur out-of-order execution timelines draw karo aur speedup do. Ports unlimited; LOAD = 3 cycles, baaki = 1 cycle. Upar wali timing convention use karo.
I1: R1 = LOAD [x] ; 3 cycles
I2: R2 = R3 + R4 ; 1 cycle, independent
I3: R5 = R1 - R6 ; 1 cycle, needs I1
I4: R7 = R2 * R8 ; 1 cycle, needs I2
Dependency graph neeche dikhaya gaya hai.

Recall Solution
In-order. I2 kyun wait karta hai? Ek strict in-order machine mein koi instruction tabhi execute begin kar sakti hai jab har pehle wali instruction begin kar chuki ho (execute stage program order mein dispatch karta hai). To in-order machine mein bhi I2 ka I1 par koi dependency nahi hone ke bawajood, woh I1 ke peeche dispatch queue mein fansa hai aur tab tak start nahi kar sakta jab tak I1 ka 3-cycle LOAD execute slot clear na kar de. Yahi ek ordering rule hai jise OoOE relax karega. Har column neeche ek cycle hai; seedha neeche padhkar dekho ki kaun sa op kaun se cycle mein hai:
Cycle: 1 2 3 4 5 6
I1: [L] [L] [L]
I2: [+]
I3: [-]
I4: [*]
Total span = 6 cycles
Out-of-order — do chains dekho: I1(3c) → I3(1c) aur I2(1c) → I4(1c). Free ports ke saath, dependencies (program order nahi) firing decide karti hain:
Cycle: 1 2 3 4
I1: [L] [L] [L]
I2: [+] (independent, fires cycle 1)
I4: [*] (needs I2 done end of cy1, fires cycle 2)
I3: [-] (needs I1 done end of cy3, fires cycle 4)
Total span = 4 cycles
- Chain 1 critical length = cycles → yahi critical path hai.
- Chain 2 length = cycles, poori tarah chain 1 ke neeche chhup jaati hai.
- Speedup .
L3.2 — Floor kahan hai?
L3.1 mein, maan lo tumhare paas infinitely many execution ports aur infinite window hain. Minimum possible completion span kya hai, aur OoOE isse beat kyun nahi kar sakta?
Recall Solution
Limit critical-path-limited ILP hai: sabse lamba dependency chain. Yahan woh I1 → I3 hai length cycles ke saath. Infinite resources ke saath bhi tum I3 ko I1 ka LOAD result aane se pehle start nahi kar sakte (ek true RAW dependency hai), isliye 4 cycles hard floor hai. OoOE unrelated work ka wait hataata hai — woh apne inputs ka wait kabhi nahi hata sakta.
Level 4 — Synthesis
L4.1 — ROB commit with a fault
Ek 8-entry ROB abhi yeh hold kar raha hai (✓ = execution complete, head marked):
ROB: [ I1✓ | I2✓ | I3(fault) | I4✓ | I5✓ | I6 | I7 | I8 ]
^head
I1, I2 cleanly finish ho gaye. I3 ne divide by zero kiya. I4, I5 finish ho gaye (speculatively). I6–I8 abhi bhi execute ho rahe hain.
(a) Kitni instructions actually apne results architectural state mein commit karti hain?
(b) I4 aur I5 ka kya hota hai, jo already answers compute kar chuke hain?
(c) Exception ke baad, machine kahan restart karti hai?
Recall Solution
Commit head se in-order hota hai, use karke.
- (a) Head aage badhta hai: I1 commit karta hai, I2 commit karta hai. Phir head = I3, jo complete hai lekin
Exceptiontrue hai ⇒ ruk jao. To fault se pehle exactly 2 instructions () commit karti hain. - (b) I4 aur I5 squash / flush ho jaate hain. Unki computed values sirf ROB ke andar rehti hain, kabhi architectural registers ya memory mein nahi jaatii, isliye woh simply khatam ho jaati hain. Isliye speculative results safe hain: fault ke baad kuch bhi kabhi visible nahi hua.
- (c) Exception handler chalta hai; architectural state = post-I2. OS cause fix kar sakta hai aur execution I3 par restart kar sakta hai. Programmer clean semantics dekhta hai: "I3 fault hua, iske baad kuch nahi hua."
L4.2 — Window ko size karna
Ek program mein abundant independent work hai lekin ek memory system hai jahan LOADs cycles lete hain. Machine average mein per cycle about instructions commit (retire) karti hai, aur uska front-end kam se kam utni hi fast issue kar sakta hai, isliye ROB full rehta hai. Roughly window mein kitni in-flight instructions honi chahiye taaki bina commit stall kiye ek 100-cycle LOAD poori tarah hide ho sake?
Recall Solution
Ek 100-cycle miss resolve hote waqt retiring jaari rakhne ke liye, window (ROB) mein commit rate ke hisaab se poori latency cover karne ke liye kaafi independent instructions honi chahiye: (Yahan issue rate ≥ commit rate hai, isliye ROB bharta hai aur commit rate woh hai jo miss ke baad sustain hona chahiye.) Yahi reason hai ki real designs windows ko 200–600 entries tak push karte hain — jitna gehri memory latency hide karni ho, utna bada window (aur ROB, physical register file, load/store buffers) hona chahiye. Is size se neeche ROB bharta hai, head outstanding LOAD par stall karta hai, aur commit halt ho jaata hai.
Level 5 — Mastery
L5.1 — Resource limit ke under design karo
L3.1 ki chaar roughly-independent instructions phir lo, lekin ab tumhare paas sirf EK execution port hai jo per cycle zyada se zyada ek instruction start kar sakta hai (ek multi-cycle LOAD woh single port apne poore 3 cycles ke liye occupy karta hai). Best out-of-order schedule banao aur in-order ke muqable naya speedup do (in-order on one port unchanged 6 cycles hai).
I1: R1 = LOAD [x] (3c, occupies the port cycles it runs)
I2: R2 = R3 + R4 (1c, independent)
I3: R5 = R1 - R6 (1c, needs I1)
I4: R7 = R2 * R8 (1c, needs I2)
Recall Solution
Ek port ke saath, port ek shared resource hai. Total work = port-cycles, isliye hum kisi bhi order mein cycle 6 se pehle khatam nahi ho sakte — execution-width-limited. Ek valid schedule (har column = ek cycle):
Cycle: 1 2 3 4 5 6
Port: [L] [L] [L] [+] [*] [-]
Op: I1 I1 I1 I2 I4 I3
I2 aur I4 tab fire karte hain jab port cycle 4 par free hota hai (I4 cycle 5 mein I2 ka result end of cycle 4 milne ke baad); I3 last fire karta hai (uska input I1 cycle 3 ke end mein ready tha, lekin port cycle 6 tak busy hai).
- Span = 6 cycles, speedup . Reordering ne yahan kuch nahi diya.
- Lesson: OoOE tabhi help karta hai jab bottleneck ke alawa koi resource idle ho. Single port poori tarah occupied hone par, tum se limited ho, jo is cheez ka middle term hai: Yeh L3.2 ka flip side hai, jahan critical path binding limit tha.
L5.2 — Kaun sa limit bind karta hai?
Har scenario ke liye, batao ki teeno limits (Window, Execution width, Critical path) mein se kaun sa bottleneck hai.
(a) Ek lamba chain A→B→C→…→Z, har ek 1 cycle, saare ports free, huge window.
(b) 1000 fully independent 1-cycle adds, 4 ports, window of 8.
(c) 1000 fully independent 1-cycle adds, 2 ports, window of 500.
Recall Solution
- (a) Critical path. 26-deep RAW chain cycles force karta hai chahe kitne bhi ports ho ya window kitni bhi badi ho — tum apni khud ki dependencies se aage nahi bhaag sakte.
- (b) Window. Independent work exist karta hai aur ports plentiful hain, lekin tum ek baar mein sirf 8 instructions dekh sakte ho, isliye tum kabhi zyada der tak 4 ports feed nahi kar sakte. Window badhaao aur IPC badhega.
- (c) Execution width. Window (500) aur independence dono kaafi hain, isliye unhi mein se koi bind nahi karta. Limiting term 2 ports hai: zyada se zyada 2 adds per cycle start ho sakte hain, isliye 1000 independent adds cycles lete hain. Zyada ports add karna speed up karega; bada window nahi.
Recall Quick self-test
Renaming se hatai jaane wali false dependencies hain ::: WAR aur WAW (RAW nahi) OoOE machine mein commit order hota hai ::: strictly in program order, ROB ke zariye Infinite resources ke saath completion time ka hard floor set karta hai ::: critical path (sabse lamba true-dependency chain) 4 commits/cycle par 100-cycle miss hide karne ke liye zaroori window lagbhag hai ::: 400 in-flight instructions L3.1 in-order vs OoOE (unlimited ports) ka speedup ::: 6/4 = 1.5×