Exercises — Tomasulo's algorithm
5.3.3 · D4· Hardware › Advanced Microarchitecture › Tomasulo's algorithm
Shuru karne se pehle, parent note ne jo chaar shared vocabulary pieces di hain, unhein yahan sabse tight form mein restate kiya gaya hai taaki exercises mein har symbol use se pehle earn kiya hua ho.
Level 1 — Recognition
Exercise 1.1 (L1)
Register file entry R7.tag = Mult2 ke liye, kya R7 abhi valid value hold kar raha hai? Plain English mein is tag ka kya matlab hai?
Recall Solution
Nahi, R7.value abhi trustworthy nahi hai. Ek non-NULL .tag "main wait kar raha hun" ka flag hai. Specifically R7.tag = Mult2 ka matlab hai: "R7 ki agli value reservation station Mult2 se aayegi. Jab Mult2 CDB par broadcast karega, R7 woh number .value mein latch kar lega aur .tag NULL kar dega." Sirf ek NULL tag ka matlab hai ki register ka .value field trustworthy hai.
Exercise 1.2 (L1)
Tomasulo ke teen stages order mein naam batao, aur har ek ke liye ek-line job do.
Recall Solution
- Issue — ek free RS grab karo, operand values ya unke producer tags copy karo, aur destination register ka
.tagis RS ke naam se stamp karo. - Execute — CDB watch karo jab tak dono aur NULL na ho jaayein, phir functional unit chalao.
- Write Result — CDB jeetto,
<RS_name, result>broadcast karo; saare listeners (RS fields + register.tagfields) jo is RS ko naam dete hain value grab karte hain;busyclear karo.
Exercise 1.3 (L1)
Ek reservation station mein , , hai (toh don't-care hai). Kya yeh instruction abhi execute karna shuru kar sakta hai? Kaun sa field ise block kar raha hai?
Recall Solution
Nahi. Execute condition hai Yahan (NULL nahi), toh doosra operand abhi bhi IOU hai aur mein koi meaningful value nahi hai. Instruction par block hai, Add1 ke broadcast ka wait kar raha hai. theek hai.
Level 2 — Application
Exercise 2.1 (L2)
Registers: R2 mein value 5 hai (tag NULL). R3.tag = Mult1 (waiting). Is ke liye exact Issue-stage field assignments dikhao:
ADD R4, R2, R3 → issues to Add1Recall Solution
Source 1 hai R2: tag NULL ⇒ hum value rakhte hain, use mein copy karo.
Source 2 hai R3: tag Mult1 ⇒ hum value nahi rakhte, tag mein copy karo (ek IOU).
Destination hai R4: uska .tag is RS ke naam se stamp karo taaki future R4 readers Add1 par wait karein.
Issue ke baad resulting state:
Sirf do "waiting" facts hain: (yeh operand ek outstanding IOU hai) aur R4.tag = Add1 (R4 ab khud Add1 par ek IOU hai). Baaki sab settled hai.
Exercise 2.2 (L2)
Exercise 2.1 continue karo. Ek later cycle mein Mult1 CDB par <Mult1, 9> broadcast karta hai. Dikhao ki Add1 mein kya changes hote hain, aur batao ki Add1 ab execute kar sakta hai ya nahi — aur is page ki clock convention ke under kaunsi cycle mein shuru karta hai.
Recall Solution
Add1.Qk == Mult1 broadcast tag se match karta hai, toh CDB latch par (broadcast cycle ke pehle aadhe mein, use cycle kaho):
Add1.Vk ← 9Add1.Qk ← NULL
Ab dono aur hain, toh Add1 ready hai, aur yeh compute karega.
Kaun si cycle mein shuru hoga? Is page ki fixed convention ke under (CDB definition box dekho): operand cycle ke pehle aadhe mein latch hota hai; ready-check cycle ke doosre aadhe mein use read karta hai; toh execution cycle mein shuru hoti hai. CDB forwarding ka matlab yeh hai ki hume 9 ko ek register mein write karke wapas read nahi karna — yahi woh cheez hai jo humein se shuru hone ka faayda deti hai, baad ki jagah.
Exercise 2.3 (L2)
MUL R1, R2, R3 → Mult1 (R2=2, R3=3, both ready)
SUB R1, R6, R7 → Add1 (R6=20, R7=8, both ready)Dono instructions issue hone ke baad (koi finish hone se pehle), R1.tag kya hai? Jab Mult1 baad mein <Mult1, 6> broadcast karta hai, toh kya R1 update hoga?
Recall Solution
MUL pehle issue karta hai: R1.tag ← Mult1.
SUB doosra issue karta hai aur R1 mein bhi likhta hai: R1.tag ← Add1 (Mult1 overwrite ho jaata hai).
Toh final R1.tag = Add1 hai.
Jab Mult1 <Mult1, 6> broadcast karta hai, Write-Result rule check karta hai "kya R1.tag abhi bhi Mult1 naam leta hai?" — nahi leta, woh Add1 naam leta hai. Toh R1 broadcast ignore karta hai. Yahi WAW hazard dissolve hota hai: earlier writer ka result silently drop ho jaata hai kyunki ek later writer ne pehle hi woh naam claim kar liya. (SUB ka 20 - 8 = 12 R1 mein land karega.)
Level 3 — Analysis
Exercise 3.1 (L3)
Is program mein jahan saare operands initially ready hain except dependencies ke through:
1. MUL R1, R2, R3 # 5 cycles
2. ADD R4, R1, R5 # 2 cycles
3. SUB R6, R1, R7 # 2 cyclesDono ADD aur SUB ko R1 chahiye (jo MUL produce karta hai). Jab MUL CDB par broadcast karta hai, ek single broadcast mein kitne stations value grab karte hain? CDB ki kaun si property yeh sasta banati hai?
Recall Solution
Dono ADD (Add1) aur SUB (Add2) ke paas Qj = Mult1 hai. Ek single broadcast <Mult1, result> simultaneously har RS dwara latch kiya jaata hai jo Mult1 ke liye sun raha hai. Toh do stations ek broadcast mein use grab karte hain — aur yeh usi ek broadcast ke saath hoga chahe das instructions bhi wait kar rahi hon.
Woh sasti property yeh hai ki CDB ek broadcast medium hai, point-to-point delivery nahi. Producer track nahi karta ki kise uska result chahiye (0 ho sakta hai, 5 ho sakta hai). Woh ek baar chillata hai; matching locally har listener dwara ki jaati hai jo apna stored tag compare karta hai. Isliye Tomasulo consumer list maintain nahi karta.
Exercise 3.2 (L3)
3.1 waala same program. WAR situation par Tomasulo ko simple scoreboard se compare karo: suppose issue karne ke baad hum add karte hain
4. ADD R5, R8, R9 # writes R5, which instruction 2 readsKya Tomasulo instruction 4 ko instruction 2 ke R5 read ko protect karne ke liye stall karta hai? Kyun / kyun nahi?
Recall Solution
Instruction 2 (ADD R4, R1, R5) R5 read karta hai. Instruction 4 R5 likhta hai. Program order kehta hai ki read ko purana R5 dekhna chahiye. Ek scoreboard, jisme koi renaming nahi, instruction 4 ke write ko stall karna padta hai jab tak instruction 2 ne R5 read na kar liya ho (ek genuine WAR stall).
Tomasulo stall nahi karta. Issue time par, instruction 2 ne already R5 ki purani value Add1.Vk mein capture kar li (ya uska producer tag copy kar liya). Instruction 4 ek naye RS mein issue karta hai aur R5.tag apne apne naam se stamp karta hai. Instruction 2 ab R5 ke liye register file bilkul nahi dekhta — uske paas apni private copy hai. Isliye WAR hazard kabhi materialize nahi hota; renaming ne har reader ko ek snapshot de diya. Scoreboarding par yahi headline advantage hai: WAR aur WAW eliminate hote hain, sirf detect nahi.
Exercise 3.3 (L3)
Parent note ke worked example mein, DIV (Mult2) Mult1 (purana R1) par nahi balki Add2 (naya R1) par wait karta hai. Trace karo kyun dependency Add2 ki taraf route hui nah ki Mult1 ki taraf, exact cycle events reference karte hue.
Recall Solution
R1 ke tag ki timeline dekho:
- Cycle 1:
MULissue karta hai,R1.tag ← Mult1. - Cycle 3:
SUBissue karta hai,R1.tag ← Add2(overwrite). - Cycle 4:
DIV R8, R1, R9issue karta hai. Yeh R1 ka tag is moment par read karta hai, joAdd2hai. TohMult2.Qj ← Add2.
DIV isliye Add2 ke liye suntta hai, correctly sabse recent R1 chahta hua (SUB ka result, 12), stale MUL result (6) nahi. Cycle 5 par Add2 <Add2, 12> broadcast karta hai, Mult2.Qj clear hota hai, aur DIV start hota hai. Register renaming ne program order automatically capture kar liya: jisne bhi R1 ka tag sabse recently apne naam rakha, wahi later reader depend karta hai.
Level 4 — Synthesis
Exercise 4.1 (L4)
Is program ke liye full issue/tag/timing trace banao. Assume: MUL=5 cyc, ADD=2 cyc, SUB=2 cyc, DIV=40 cyc; single CDB with oldest-first arbitration; CDB definition box mein fix ki gayi clock convention (operand latched cycle ⇒ execute starts ; -cycle op starting cycle finishes , broadcasts if it wins the bus); ek RS per unit as needed (Mult1, Mult2, Add1, Add2). Ek instruction per cycle issue hoti hai, cycle 1 se shuru. Initial: R2=6, R3=4, R5=1, R6=30, R7=10, R9=3.
1. MUL R1, R2, R3
2. SUB R1, R6, R7
3. ADD R4, R1, R5
4. DIV R8, R1, R9Do: (a) kaun sa RS har instruction issue hoti hai, (b) issue par har instruction ki operand state, (c) issue / execute-start / execute-finish / writeback cycle numbers kisi bhi CDB-arbitration stalls ke saath, (d) har numeric result, (e) kya MUL ka broadcast koi use karta hai.
Recall Solution
(a) RS assignment (program order mein, ek per free slot):
- MUL → Mult1, SUB → Add1, ADD → Add2, DIV → Mult2.
(b) Issue par operand state:
- MUL (Mult1): R2,R3 ready ⇒
Vj=6, Vk=4, Qj=NULL, Qk=NULL. SetsR1.tag = Mult1. - SUB (Add1): R6,R7 ready ⇒
Vj=30, Vk=10, Qj=NULL, Qk=NULL. SetsR1.tag = Add1(Mult1 overwrite hota hai). - ADD (Add2): R1 read karta hai (tag ab
Add1) aur R5 (ready) ⇒Qj=Add1, Vk=1. SetsR4.tag = Add2. - DIV (Mult2): R1 read karta hai (tag abhi bhi
Add1) aur R9 (ready) ⇒Qj=Add1, Vk=3. SetsR8.tag = Mult2.
(c) Cycle-by-cycle timing. Fixed convention step by step apply karo:
- MUL cycle 1 issue, operands issue par ready ⇒ execute cycle 2 start, finish , broadcast cycle 7 (bus free) —
<Mult1, 24>. - SUB cycle 2 issue, operands issue par ready ⇒ execute cycle 3 start, finish , broadcast cycle 5 (bus free) —
<Add1, 20>. - ADD cycle 3 issue, lekin (waiting). Add1 ki value CDB par cycle 5 mein aayegi ⇒ ADD ka ready-check cycle 5 pass karta hai ⇒ execute cycle 6 start, finish , cycle 8 par bus chahiye.
- DIV cycle 4 issue, also . Same cycle-5 broadcast ise clear karta hai ⇒ execute cycle 6 start, finish , cycle 46 par bus chahiye.
CDB-arbitration check. Har result ke liye cycles list karo jo chahte hain bus: cycle 5 (SUB), cycle 7 (MUL), cycle 8 (ADD), cycle 46 (DIV). Charon distinct hain, toh oldest-first arbitration ko yahan kabhi tie break nahi karna padata — koi writeback stall nahi hoti.
| Instr | RS | Issue | Exec start | Exec finish | Writeback (CDB) | Waited on |
|---|---|---|---|---|---|---|
| MUL | Mult1 | 1 | 2 | 6 | 7 | — |
| SUB | Add1 | 2 | 3 | 4 | 5 | — |
| ADD | Add2 | 3 | 6 | 7 | 8 | Add1 (new R1) |
| DIV | Mult2 | 4 | 6 | 45 | 46 | Add1 (new R1) |
(d) Numeric results:
- MUL .
- SUB ← yahi R1 hai jo baad ke saare downstream use karte hain.
- ADD (SUB ka 20 use karta hai).
- DIV (SUB ka 20 use karta hai).
(e) Kya MUL ka broadcast use hota hai? Nahi. Jab MUL cycle 7 par <Mult1, 24> broadcast karta hai, R1.tag Add1 hai (Mult1 nahi), aur koi RS ke paas Qj/Qk = Mult1 nahi hai (ADD aur DIV dono ne Add1 capture kiya tha, kyunki SUB ne tag unke issue se pehle overwrite kiya). MUL ka result compute hota hai aur throw away ho jaata hai — ek dead value. Yahi WAW hazard resolve hota hai: overwritten write ka result kuch harm nahi karta.
Exercise 4.2 (L4)
Exercise 4.1 mein, ADD aur DIV dono ke paas Qj = Add1 hai. Jab Add1 (SUB) cycle 5 par <Add1, 20> broadcast karta hai, kitne latches fire hote hain, aur kaun se fields mein? Unhe list karo.
Recall Solution
Broadcast <Add1, 20> har stored tag se compare hota hai. Matches:
Add2.Qj == Add1→Add2.Vj ← 20,Add2.Qj ← NULL(ADD ka operand).Mult2.Qj == Add1→Mult2.Vj ← 20,Mult2.Qj ← NULL(DIV ka operand).R1.tag == Add1→R1.value ← 20,R1.tag ← NULL(register file update).
Teen latches ek broadcast se fire hote hain: do RS operands aur ek register file entry. Sab same cycle mein — shared CDB ka yahi poora point hai. Aur yeh ek CDB slot mein fit hote hain kyunki yeh ek producer broadcasting hai; one-per-cycle limit producers ko constrain karta hai, listeners ko nahi.
Level 5 — Mastery
Exercise 5.1 (L5)
Ek designer propose karta hai register-file ke .tag fields remove karna, sirf RS tags rakhna, area bachane ke liye. Instructions Issue par register file se directly operand values read karengi, aur agar value "not ready" hai toh unhe... pata hi nahi chalega. Precisely explain karo kaun si hazard class tooti, aur ek 2-instruction counterexample construct karo jo galat result produce kare. Phir minimal fix batao.
Recall Solution
Kaun si hazard tooti: RAW (true data dependency), read-after-write. Register-file .tag field ek hi mechanism hai jo consumer ko batata hai "jo value tum chahte ho woh abhi produce nahi hui — yahan producer ka naam hai jis par wait karo." Ise delete karo aur ek consumer jo apne producer ke finish hone se pehle issue karta hai stale .value bits read karega aur unhe valid treat karega.
Counterexample:
1. MUL R1, R2, R3 # R2=2, R3=3 → R1 should become 6, takes 5 cycles
2. ADD R4, R1, R5 # R5=10, issues at cycle 2, R1 not yet 6Bina register tags ke, cycle 2 par instruction 2 R1 ka purana (stale) content read karta hai — kaho MUL se pehle ki value 99 — aur R4 = 99 + 10 = 109 compute karta hai. Sahi answer hai 6 + 10 = 16. Galat result, silently.
Minimal fix: har register par kam se kam ek .tag field rakho taaki Issue par ek consumer detect kar sake "not ready" aur producing RS ka naam apne mein copy kar sake. Yeh irreducible hai — Tomasulo ka renaming hai hi register tag mechanism; RS tags akele register-file boundary bridge nahi kar sakte. (Related structure ke liye reorder-buffer dekho jo per-value producer info bhi carry karta hai.)
Exercise 5.2 (L5)
Maan lo CDB sirf ek broadcast per cycle carry kar sakta hai, lekin kisi cycle mein do functional units simultaneously finish hote hain (Mult1 aur Add1 dono done). Is page ki oldest-first arbitration policy use karte hue, structural conflict describe karo, kaun sa unit jeetta hai, ILP par uska effect jo tum extract kar sakte ho, aur do realistic design responses.
Recall Solution
Conflict: ek shared broadcast wire hai, toh zyada se zyada ek FU per cycle write kar sakta hai. Do finishers us par compete karna ek structural hazard hai bus par hi.
Kaun jeetta hai: is page ki fixed policy se, program order mein sabse purana instruction is cycle broadcast karta hai; younger wala apna Write-Result stage stall karta hai (uska RS busy rehta hai, finished value hold karte hue) aur agli free cycle mein retry karta hai. Concretely, agar Mult1 purana instruction hold karta hai, Mult1 ab broadcast karta hai aur Add1 ek cycle wait karta hai.
ILP par effect: har stalled writeback us moment ko delay karta hai jab dependent instructions apne operands receive karte hain, jo unka execute start delay karta hai, downstream ripple karta hua. Jaise issue width aur FU count badhte hain, ek single CDB throughput bottleneck ban jaata hai — tum compute parallel mein kar sakte ho lekin results publish parallel mein nahi kar sakte.
Do design responses:
- Multiple CDBs (e.g., 2–4 buses). Har RS/register ab several buses snoop karta hai; zyada comparators, zyada area, lekin concurrent broadcasts. Real superscalar Tomasulo machines yahi karte hain.
- Arbitration + write buffering — har cycle winner choose karne ke liye fixed oldest-first priority rakho; losers ek chhote write buffer mein queue karte hain. Wires mein sasta, lekin writeback bandwidth ek per cycle par cap ho jaati hai, toh yeh sirf tab help karta hai jab simultaneous finishes rare hon.
Exercise 5.3 (L5)
Tomasulo jaise originally describe kiya gaya (parent note ke per) mein koi reorder buffer nahi hai aur isliye results compute hote hi commit karta hai. Explain karo kyun yeh precise exceptions impossible banata hai, aur ROB bolt on karna unhe kaise restore karta hai — wapas connect karte hue ki same renaming machinery abhi bhi kyun kaam karti hai. Figure reference karo.

Recall Solution
Kyun precise exceptions toot jaate hain: plain Tomasulo mein, ek later instruction (program order mein) finish ho sakta hai aur register file mein pehle apna result write kar sakta hai, out of order. Figure dekho: SUB finish hota hai aur R1 cycle 5 par update karta hai, jabki earlier MUL cycle 6 tak chal raha hai. Agar MUL ab ek exception raise karta hai (maan lo overflow), machine ki visible register state already ek younger instruction dwara alter ho chuki hai (SUB ka write, aur possibly doosre). Koi clean point nahi hai yeh kehne ke liye "architectural state exactly waise hai jaise instructions 1..k complete hui hain aur k+1 onward nahi" — yahi precise exception ki definition hai, aur yeh impossible hai jab younger writes leak ho chuki hon.
ROB kaise fix karta hai: ek reorder buffer insert karo — program order mein ek FIFO queue. Ab Write-Result value instruction ke ROB slot mein deposit karta hai, register file mein nahi. Instructions abhi bhi execute out of order karte hain (throughput preserved), lekin woh commit (architectural register file mein write) strictly program order mein karte hain, ROB ke head se ek per cycle. Jab MUL ka exception discover hota hai, MUL se younger sab kuch ROB mein abhi bhi uncommitted baitha hai aur simply flush kiya ja sakta hai — architectural registers unse kabhi touch nahi hue.
Renaming abhi bhi kyun kaam karta hai: tags ab RSs ki jagah ROB entries naam dete hain, aur CDB <ROB_index, value> broadcast karta hai. Exact same IOU-and-broadcast mechanism chalta hai; humne sirf naam kis cheez ko refer karta hai change kiya aur ant mein ek in-order commit gate add kiya. Out-of-order execution + in-order commit = full speed with precise state. (Yahi standard modern out-of-order pipeline hai.)
Do figures neeche woh visual intuition carry karte hain jo tables sirf summarize karte hain — ek broadcast fan-out aur ek out-of-order timeline.

Upar ki picture Exercise 4.2 ka jawab hai: ek producer, ek CDB slot, teen simultaneous listener latches.
Recall Self-test cloze (yeh last mein karo, memory se)
Execute condition require karta hai ==both = NULL and = NULL==.
Ek non-NULL register .tag ka matlab hai register waiting for the named RS to broadcast hai.
Tomasulo WAR aur WAW hazards eliminate karta hai register renaming (RS/ROB tags) ke zariye.
CDB ek broadcast medium hai jo one result per cycle carry karta hai, all listeners whose stored tag matches dwara captured.
Precise exceptions ke liye ek reorder buffer add karna zaroori hai taaki instructions commit in program order karein.
Execute condition in symbols?
.tag = Add2 wala register abhi kya hold karta hai?
Kyun ek overwritten producer ka result kuch harm nahi karta?
Ek CDB, do finishers — is page ki policy ke under kaun jeetta hai?
CDB snoop karne wale do listener groups kaun se hain?
.tag field.