處理器架構練習題 (Practice - Processor Architecture)
Related Concepts
- 04-Processor-Architecture/01-Y86-64-ISA
- 04-Processor-Architecture/02-Logic-Design-and-HCL
- 04-Processor-Architecture/03-Sequential-SEQ-Implementation
- 04-Processor-Architecture/04-Pipelining-Principles
- 04-Processor-Architecture/05-Pipelined-PIPE-Implementation-and-Hazards
| 關鍵字 | 答案 |
|---|---|
| Y86-64 registers | 15 個 64-bit(無 %r15);ID 0xF = no register |
| 設定 condition codes 的指令 | 只有 OPq(addq/subq/andq/xorq) |
| 指令編碼 | code:fn + rA:rB(空欄補 F)+ 8-byte 常數 little-endian |
| jXX / call 定址 | 絕對位址(非 PC-relative) |
| HCL case expression | 條件不需互斥;依序取第一個為 1 的 case;default 寫 1: |
| subq 的 ALU 計算 | valE ← valB − valA(valB 在前) |
| pushq / popq 記憶體位址 | pushq 用 valE(先減 8);popq 用 valA(未遞增) |
| new PC 三來源 | valP(循序)、valC(call/taken jXX)、valM(ret) |
| 時脈週期 | max(stage 延遲) + register 延遲;GIPS = 1000/週期(ps) |
| 管線化 trade-off | throughput 提升、latency 略增(register overhead) |
| 轉發優先序 | execute > memory > write-back;同階段 valM > valE |
| load/use hazard | stall 1 cycle + forward(load interlock) |
| ret / 誤預測分支代價 | 3 bubbles / 2 bubbles |
| CPI | 1.0 + lp + mp + rp;每項 = 指令頻率 × 條件頻率 × bubble 數 |
Question 1 - Programmer-Visible State [recall]
Y86-64 的 programmer-visible state 包含哪些元件?program registers 有幾個?與 x86-64 相比少了哪一個、為什麼?
15 個 64-bit program registers(%rax–%rdi、%r8–%r14)+ 3 個 condition codes(ZF/SF/OF)+ PC + memory + Stat(程式狀態碼)。
相比 x86-64 省略了 %r15,目的是簡化指令編碼(register ID 只需 0–0xE,0xF 留作 no register)。
Question 2 - Condition Codes 與 OPq 限制 [recall]
Y86-64 中哪些指令會設定 condition codes?OPq 指令的運算元有什麼限制?若想計算「%rax 加上常數 8」需要幾條指令?
只有 OPq(addq/subq/andq/xorq)會設定 ZF/SF/OF;irmovq、rrmovq、cmovXX 等都不會。
OPq 只能作用於 register–register,不允許 immediate 或 memory 運算元(load/store 架構的 RISC 特徵)。
因此加常數需要兩條指令:先 irmovq $8, %rbx(常數載入暫存器),再 addq %rbx, %rax。
Question 3 - 指令編碼 [application]
寫出下列兩條指令的 byte 編碼(hex):
subq %rdx, %rbx
irmovq $4, %rcx
subq %rdx, %rbx → OPq code=6、subq fn=1,rA=%rdx=2、rB=%rbx=3 → 61 23(2 bytes)。
irmovq $4, %rcx → code:fn=30,register byte = F1(來源欄補 0xF、rB=%rcx=1),常數 4 補足 8 bytes 後 little-endian 反序 → 30 F1 04 00 00 00 00 00 00 00(10 bytes)。
Question 4 - Stat 狀態碼 [recall]
列出 Y86-64 的四種 Stat 狀態碼(名稱與意義)。本章的簡化設計中,遇到非 AOK 的狀態時處理器會怎麼做?
AOK=1(正常執行)、HLT=2(執行了 halt)、ADR=3(取指或讀寫非法記憶體位址)、INS=4(非法 instruction code)。
簡化設計中,只要 Stat 非 AOK,處理器就直接停止執行;完整設計則會呼叫 exception handler(見第 8 章)。
Question 5 - HCL Case Expression [recall]
HCL 的 case expression 與 C 的
switch有哪些關鍵差異?default case 怎麼寫?這個特性如何幫助化簡選擇運算式?
差異:各選擇條件不需互斥;邏輯上依序求值,取第一個結果為 1 的 case;default 是最後一條選擇運算式直接寫 1 :。
化簡:因為「只選第一個符合者」,後面的 case 可省略已被前面攔截的條件——例如 4-way MUX 第二條只需寫 !s1(不必寫 !s1 && s0),MIN3 第二條只需 B <= C : B;。
Question 6 - SEQ 六階段 [recall]
依序列出 SEQ 處理指令的六個階段,並指出各階段產生的主要訊號。new PC 有哪三個可能的來源?
Fetch(icode/ifun/rA/rB/valC/valP)→ Decode(valA/valB)→ Execute(valE、Cnd、Set CC)→ Memory(valM)→ Write back(經 E/M 兩埠寫回 register file)→ PC update。
new PC 三來源:valP(循序下一條)、valC(call 與 taken jXX)、valM(ret 從 stack 彈出的返回位址)。
Question 7 - SEQ 指令追蹤 [application]
SEQ 執行
pushq %rdx時,已知 R[%rsp]=0x108、R[%rdx]=9,指令位於位址 0x030。
寫出各階段的具體計算:valP、valA、valB、valE、記憶體動作與寫回結果。
Fetch:valP = 0x030 + 2 = 0x032(pushq 長 2 bytes)。
Decode:valA = R[%rdx] = 9;valB = R[%rsp] = 0x108。
Execute:valE = valB + (−8) = 0x100。
Memory:M8[0x100] ← 9(寫入位址用遞減後的 valE)。
Write back:R[%rsp] ← valE = 0x100;PC ← valP = 0x032。
Question 8 - pushq 與 popq 的位址慣例 [recall]
pushq 的記憶體寫入位址與 popq 的記憶體讀取位址分別使用哪個訊號?
popq %rsp執行後 %rsp 的值是什麼(E、M 兩個寫入埠如何取捨)?
pushq 用 valE(%rsp − 8,「先減後寫」);popq 用 valA(未遞增的 %rsp,「先讀再加 8」)。
popq %rsp 時 E 埠(valE)與 M 埠(valM)位址相同,規定 M port 優先,故 %rsp 得到從記憶體讀出的值 valM,等價於 mrmovq (%rsp), %rsp。
Question 9 - No Reading Back 原則 [recall]
SEQ 時序設計中的「no reading back」原則是什麼?以 pushq 為例說明此原則如何被遵守。
原則:處理器永遠不需要讀回「本指令更新後的狀態」來完成本指令的處理。
pushq 若先把 %rsp−8 寫回、再讀更新後的 %rsp 當寫入位址就違反原則;正確做法是 ALU 產生 valE 這一個訊號,同時作為寫回 %rsp 的資料與記憶體寫入位址,兩個寫入在 clock 上升時同時發生。CC 同理:沒有指令既設定又讀取 CC。
Question 10 - 管線計算題 [application]
一個 3-stage 管線各段組合邏輯延遲為 80 / 120 / 100 ps,每個 pipeline register 延遲 20 ps。
求:最小時脈週期、throughput(GIPS)、latency。哪個 stage 每週期閒置最久?
週期 = max(stage 延遲) + register 延遲 = 120 + 20 = 140 ps。
Throughput = 1000 / 140 ≈ 7.14 GIPS;Latency = 3 × 140 = 420 ps。
閒置最久的是最快的 stage A(80 ps):每週期閒置 120 − 80 = 40 ps——nonuniform partitioning 使週期被最慢 stage 綁死。
Question 11 - Clock 快慢的影響 [recall]
在管線系統中,把 clock 放慢會發生什麼事?把 clock 調得太快又會發生什麼事?為什麼兩者不對稱?
放慢:行為不變——訊號早已抵達 pipeline register 輸入端,register 要等 clock 上升緣才載入新狀態。
太快:災難性錯誤——訊號來不及傳過組合邏輯,clock 上升時 register 輸入端的值尚未有效 (not yet valid)。
不對稱的根源:register 只在 rising edge 取樣輸入,早到的值可以等,晚到的值救不回來。
Question 12 - Forwarding 來源與優先序 [recall]
PIPE 的 forwarding 有哪 5 個來源、哪 2 個目的地?轉發優先序的原則是什麼、為什麼?
5 個來源:e_valE、m_valM、M_valE、W_valM、W_valE;2 個目的地:decode 階段的 valA、valB。
優先序:越早的管線階段越優先(execute > memory > write-back),因為較早階段持有程式順序上「最新」寫該暫存器的指令;同一階段內 valM 優先於 valE(只影響 popq %rsp)。
Question 13 - 管線控制動作 [recall]
什麼是 bubble?寫出三種控制情況(processing ret、load/use hazard、mispredicted branch)各自在 F、D、E 三個管線暫存器的控制動作與代價。
Bubble = 動態產生的 nop:不改暫存器、記憶體、CC 或狀態。
ret:F stall / D bubble / E normal,共 3 bubbles;load/use:F stall / D stall / E bubble,1 bubble;mispredicted branch:F normal / D bubble / E bubble,2 bubbles(squash 兩條誤抓指令)。
Question 14 - Load/Use Hazard 分析 [analysis]
考慮以下 Y86-64 片段:
mrmovq 0(%rdx), %rax
addq %rbx, %rax
為什麼純 forwarding 無法解決這個 hazard,而一般的 OPq→OPq 相依卻可以?PIPE 實際採用什麼機制、偵測條件為何?
OPq 的結果 e_valE 在 execute 階段結尾就產生,來得及轉發給下一條指令的 decode;但 mrmovq 的讀出值 m_valM 要到 memory 階段才產生,晚於緊接其後指令的 decode——純轉發需要值「倒流時光」。
解法:load interlock = stall 1 cycle + forwarding(下個 cycle 由 m_valM 轉發)。
偵測條件:E_icode in { IMRMOVQ, IPOPQ } && E_dstM in { d_srcA, d_srcB }。這是唯一會因 forwarding 不足而損失吞吐量的 data hazard。
Question 15 - 控制組合 B 分析 [analysis]
當 execute 階段是一條寫入 %rsp 的 mrmovq、而 decode 階段是 ret 時,load/use hazard 與 processing ret 兩種條件同時成立。
天真地把兩組控制動作用 OR 合併,D 暫存器會發生什麼錯誤?正確的處理方式是什麼?這個案例給硬體設計什麼教訓?
天真合併:load/use 要求 D stall、ret 要求 D bubble,兩者同時為 1 是錯誤狀態(設計上禁止),會使 ret 指令直接消失。
正確做法:只採 load/use 的動作(F stall / D stall / E bubble),把 ret 的處理延後一個 cycle——%rsp 先轉發到位,ret 才能正確彈出返回位址。
教訓:作者原始設計正是在此有 bug,大量模擬測試都沒抓到,靠系統化分析所有指令組合才揪出——硬體出廠後無法修補,看似無意義的組合(如 popping to the stack pointer)也必須驗證。
Question 16 - CPI 效能分析 [application]
某 PIPE 處理器:load 指令占 25%(其中 20% 造成 load/use)、條件分支占 20%(誤預測率 40%)、ret 占 2%(必停)。
bubble 數分別為 1、2、3。計算 CPI,並指出最值得優先改善的項目。
lp = 0.25 × 0.20 × 1 = 0.05;mp = 0.20 × 0.40 × 2 = 0.16;rp = 0.02 × 1.00 × 3 = 0.06。
CPI = 1.0 + 0.05 + 0.16 + 0.06 = 1.27。
優先改善 mispredicted branch(占 0.27 中的 0.16):可改用更好的預測策略(如 BTFNT,成功率約 65%,mp 降為 0.14)或以條件搬移取代條件跳轉。
| 題型 | 答題模式 |
|---|---|
| 指令編碼題 | code:fn → rA:rB(單 register 補 F)→ 常數補 8 bytes 後 byte-reversed(little-endian) |
| 「哪些指令設定 CC?」 | 一律回答:只有 OPq |
| SEQ trace 填表 | 套六階段 generic 表,代入具體值;subq 記住 valB − valA |
| push/pop 位址題 | pushq 寫入用 valE(先減);popq 讀取用 valA(未遞增);popq %rsp 取 valM(M 埠優先) |
| 管線計算題 | 週期 = max(stage) + register 延遲;GIPS = 1000/週期;latency = 段數 × 週期 |
| 深管線極限 | throughput 上限 = 1 / register 延遲(固定 overhead) |
| 轉發題 | 5 來源 → 2 目的地;優先序 execute > memory > write-back |
| hazard 代價題 | load/use = 1 bubble、mispredict = 2、ret = 3 |
| CPI 題 | CPI = 1.0 + Σ(指令頻率 × 條件頻率 × bubble 數) |
| 控制組合題 | 條件同時成立時逐暫存器合併動作;stall + bubble 同時為 1 即設計錯誤 |