大二下計算機結構

19008 字
95 分鐘
大二下計算機結構

第一章:程式效能解析與底層硬體邏輯#

1. 效能的定義與度量 (Performance)#

核心觀念辨析#

指標定義適用情境改善手段
Response Time電腦完成單一任務所需的總時間(從開始到結束)。個人電腦、行動裝置、嵌入式系統。提升處理器主頻、優化編譯器、改善演算法。
Throughput電腦在單位時間內所能完成的任務總量。資料中心、雲端伺服器、網路設備。增加處理器核心數、引進硬體平行處理技術。

程式翻譯與抽象化層次 (Abstraction)#

  1. 高階語言 (High-Level Language):如 C, C++, Java。人類易讀,具備高抽象度。
  2. 編譯器 (Compiler):負責將高階語言翻譯成特定架構的組合語言 (Assembly Language)(如 RISC-V, x86)。
  3. 組譯器 (Assembler):將組合語言翻譯成硬體唯一能讀懂的目的碼/機器語言 (Machine Language)(由二進位 0 與 1 組成)。
  4. 指令集架構 (ISA, Instruction Set Architecture):軟體與硬體之間的底層合約介面。它定義了硬體支援的指令、暫存器個數、定址模式與資料型態,使軟體開發者與硬體設計師能各自獨立優化。

2. 計算機效能 (Performance Equations)#

效能公式#

CPU Execution Time=Instruction Count (IC)×CPI×Clock Cycle Time (Tc)\text{CPU Execution Time} = \text{Instruction Count (IC)} \times \text{CPI} \times \text{Clock Cycle Time } (T_c)

CPU Execution Time=Instruction Count (IC)×CPIClock Rate (f)\text{CPU Execution Time} = \frac{\text{Instruction Count (IC)} \times \text{CPI}}{\text{Clock Rate } (f)}


一、 指令總數 (Instruction Count, IC)#
  • 定義:執行完某個特定程式,CPU 總共需要執行的機械碼(機器指令)總條數。
  • 物理意義:代表該任務的工作量大小
  • 決定因素:主要由軟體層面決定,包含演算法效率、原始碼寫法、程式語言特性,以及編譯器(Compiler)的優化能力。
二、 每條指令平均週期數 (Cycles Per Instruction, CPI)#
  • 定義:程式執行期間,平均每執行一條硬體指令所需要消耗的時脈週期(Clock Cycle)數量。
  • 物理意義:反映了硬體架構執行指令的效率
  • 計算特性:因為不同的指令(例如整數加法與浮點數除法)其複雜度與所需週期大不相同,工程實務上必須採用加權平均法計算: 平均 CPI=i=1n(該指令型態所需的 CPIi×該指令在程式中所佔的比例i)\text{平均 CPI} = \sum_{i=1}^{n} (\text{該指令型態所需的 CPI}_i \times \text{該指令在程式中所佔的比例}_i)
  • 決定因素:主要由指令集架構(ISA)與處理器的微架構(Microarchitecture,如管線化、快取記憶體設計、超純量等)決定。
三、 時脈週期時間 (Clock Cycle Time, TcT_c)#
  • 定義:處理器內部時鐘(振盪器)每跳動一下(一個電位脈衝)所花費的實際時間,通常以奈秒(nsns, 10910^{-9} 秒)或皮秒(psps, 101210^{-12} 秒)為單位。
  • 物理意義:代表 CPU 執行最基本硬體動作的最小時間單位(節拍)
四、 時脈頻率 / 主頻 (Clock Rate, ff)#
  • 定義:處理器內部的時鐘在單位時間(通常為一秒)內跳動的次數,單位為赫茲(Hz),目前主流處理器多以吉赫茲(GHz, 10910^9 Hz)度量。
  • 物理意義與關係:時脈頻率 ff 與時脈週期時間 TcT_c 互為倒數關係。 f=1Tcf = \frac{1}{T_c} 例如:若 Tc=0.2 nsT_c = 0.2 \text{ ns},則其時脈頻率 f=10.2×109=5×109 Hz=5 GHzf = \frac{1}{0.2 \times 10^{-9}} = 5 \times 10^9 \text{ Hz} = 5 \text{ GHz}
  • 決定因素:由硬體電路設計、流水線切分的深度,以及半導體晶圓製程(如 3nm, 2nm 工藝)共同決定。

影響因素對照表#

下表呈現了軟硬體各層面對於效能鐵三角中三大因子的牽制關係:

影響層面指令總數 (IC)平均每條指令週期數 (CPI)時脈頻率 / 週期時間 (ff / TcT_c)
演算法 (Algorithm)主導影響間接影響無影響
程式語言 (Programming Language)主導影響間接影響無影響
編譯器 (Compiler)顯著影響顯著影響無影響
指令集架構 (ISA)決定性定義顯著影響顯著影響
硬體微架構 (Microarchitecture)無影響主導影響顯著影響
半導體製程 (IC Fabrication)無影響無影響決定性影響

💡 提示 考試常見的「架構二選一」或「優化方案評估」題型,解題核心在於分別算出變更前後的 CPU 執行時間(ToldT_{\text{old}}TnewT_{\text{new}}),再透過相除求得加速比(Speedup=ToldTnew\text{Speedup} = \frac{T_{\text{old}}}{T_{\text{new}}})。切記不要只偏看單一因子的進步。


3. 動態功耗公式與功耗牆 (Power Wall)#

動態功耗公式#

Powerdynamic=Capacitive Load×Voltage2×Frequency\text{Power}_{\text{dynamic}} = \text{Capacitive Load} \times \text{Voltage}^2 \times \text{Frequency}

功耗牆 (Power Wall) 的成因與轉折#

  • 成因:在過往,工程師透過提高工作頻率(Frequency)來壓榨單核心效能。然而,頻率上升迫使晶片發熱量劇增。若想壓低功耗,就必須降低電壓(Voltage)。但當電壓降至接近臨界值時,晶片會產生嚴重的靜態漏電流(Leakage Current)。
  • 結果:電壓無法再降,導致工作頻率無法再往上突破,此物理限制稱為「功耗牆」。
  • 對策:微處理器設計從「拉高單核心頻率」轉向「單一晶片內建多核心 (Multicore)」,透過並行處理(Parallelism)在較低頻率下獲取更高的吞吐量。

4. 阿姆達爾定律 (Amdahl’s Law)#

整體加速比公式#

Speedupoverall=1(1F)+FS\text{Speedup}_{\text{overall}} = \frac{1}{(1 - F) + \frac{F}{S}}

  • FF (Fraction Enhanced):程式中可以被特定優化手段加速的部分所佔的時間比例(0F10 \le F \le 1)。
  • SS (Speedup Enhanced):該特定優化部分自身獲得的效能提升倍率
  • (1F)(1 - F):程式中無法被優化、必須維持循序(Sequential)執行的瓶頸部分。

物理啟示#

  • 系統整體的效能提升上限,受到「不可並行/不可優化」部分的嚴重制約。
  • 當投入無限硬體資源使得該局部優化倍率趨近於無限大(SS \to \infty)時,整體的最大加速比極限為: limSSpeedupoverall=11F\lim_{S \to \infty} \text{Speedup}_{\text{overall}} = \frac{1}{1-F}

📝 實戰演練:局部加速與整體降頻#

經典考題: 某處理器的浮點數運算佔總程式執行時間的 60%。你開發了一套新的硬體加速器,能讓浮點數運算變快 4 倍,但為了散熱,不得不將處理器的整體時脈頻率 (Clock Rate) 降低 10%。

  1. 請計算整個程式最終的 Speedup 是多少?
  2. 這個改良方案值得採用嗎?
【解析】#

最終整體 Speedup=純架構優化 Speedup (阿姆達爾定律)×時脈頻率變動率\text{最終整體 Speedup} = \text{純架構優化 Speedup (阿姆達爾定律)} \times \text{時脈頻率變動率}

第一步:套用阿姆達爾定律,計算「純架構優化」的倍率 根據題目條件,提取公式參數:

  • 可被優化的比例 F=60%=0.6F = 60\% = 0.6
  • 該局部的加速倍率 S=4S = 4

代入阿姆達爾定律公式,求出若在「頻率不變」的前提下,單靠加速器帶來的架構內在加速比: 純架構 Speedup=1(1F)+FS=1(10.6)+0.64=10.4+0.15=10.55\text{純架構 Speedup} = \frac{1}{(1 - F) + \frac{F}{S}} = \frac{1}{(1 - 0.6) + \frac{0.6}{4}} = \frac{1}{0.4 + 0.15} = \frac{1}{0.55}

第二步:乘上「整體降頻 10%」的修正因子 時脈頻率(Clock Rate)降低 10%,代表新頻率變為原來的 90%90\%(即 0.90.9 倍)。 因為效能與頻率成正比,頻率變慢會對效能帶來 0.90.9 倍的無差別懲罰,故將第一步的結果乘以頻率變動率:

最終整體 Speedup=純架構 Speedup×新頻率比例\text{最終整體 Speedup} = \text{純架構 Speedup} \times \text{新頻率比例} 最終整體 Speedup=10.55×0.9=0.90.55=18111.64 倍\text{最終整體 Speedup} = \frac{1}{0.55} \times 0.9 = \frac{0.9}{0.55} = \frac{18}{11} \approx \mathbf{1.64 \text{ 倍}}


5. 補充#

  1. 時間與頻率單位換算

    • 頻率單位:1 GHz=103 MHz=109 Hz1\text{ GHz} = 10^3\text{ MHz} = 10^9\text{ Hz}
    • 時間單位:1 ms=103 s1\text{ ms} = 10^{-3}\text{ s}1 μs=106 s1\text{ }\mu\text{s} = 10^{-6}\text{ s}1 ns=109 s1\text{ ns} = 10^{-9}\text{ s}1 ps=1012 s1\text{ ps} = 10^{-12}\text{ s}
    • 核心公式:實際執行時間 (秒)=總時脈週期數時脈頻率 (Hz)\text{實際執行時間 (秒)} = \frac{\text{總時脈週期數}}{\text{時脈頻率 (Hz)}}
  2. CPI 平均計算(考題常客): 題目若給出各類指令的數量或百分比,務必使用加權平均法計算出該程式的「平均 CPI」,再代入效能鐵三角公式。

  3. MIPS 指標的缺陷: MIPS(Millions of Instructions Per Second,每秒百萬條指令數)不能單獨作為評估兩台電腦效能的依據。因為 MIPS 忽略了指令總數(IC)的差異;不同的指令集架構跑同一個程式時需要的指令數不同,MIPS 高不代表執行時間短。

  4. 阿姆達爾定律變形題(多處優化): 若考題同時對多個獨立區塊進行硬體優化,分母應擴充為所有區塊的加總: Speedupoverall=1(1F1F2)+F1S1+F2S2+\text{Speedup}_{\text{overall}} = \frac{1}{(1 - F_1 - F_2 - \dots) + \frac{F_1}{S_1} + \frac{F_2}{S_2} + \dots} 注意:若優化伴隨著「整體硬體降頻」,必須在計算完上述架構優化時間後,再將時間除以頻率變動率(如降頻 10% 則時間乘以 10.9\frac{1}{0.9})。


第二章:MIPS 和指令集架構 (ISA)#

1. 指令集基礎與算術運算#

知識點 1:計算機架構定義與設計原則#

觀念與公式#
  • 核心公式: Architecture=ISA+Machine Organization\text{Architecture} = \text{ISA} + \text{Machine Organization}
  • ISA (指令集架構): 硬體與軟體的「合約」。規定了暫存器、指令格式、定址模式。
  • Organization (機組組織): 硬體的「實現」。例如 Pipeline 長度、Cache 大小。
  • 設計原則 1: Simplicity favors regularity\text{Simplicity favors regularity} (簡單源於規律性)。為了讓硬體解碼變快,MIPS 堅持指令格式必須整齊。
實戰演練#

Q:Intel i9 與 AMD Ryzen 設計不同,為何能跑同一個執行檔? A: 因為它們擁有相同的 ISA (x86-64),即硬體接口合約相同;但它們的內部 Organization (微架構) 不同,所以效能表現有異。

知識點 2:MIPS 算術指令與語法#

觀念與公式#
  • 語法規矩: op dst, src1, src2 (1 個操作碼,3 個運算元)。
  • 硬體限制: 即使 C 語言寫 f = g + h + i,MIPS 也必須拆成兩行。
實戰演練#

Q:將 f = (g + h) - (i + j) 翻譯為 MIPS。 Step-by-step:

  1. add $t0, $s1, $s2 # t0=g+ht0 = g + h
  2. add $t1, $s3, $s4 # t1=i+jt1 = i + j
  3. sub $s0, $t0, $t1 # f=t0t1f = t0 - t1

⚠️ 考前避坑指南:第 1 節#

  • 陷阱: 指令順序。永遠是 目的地 在最前面,來源 在後面。
  • 區分: 相同 ISA 的 CPU 執行結果一定一樣,但「執行時間」不一定一樣(因為 Organization 不同)。

2. 記憶體運算元 (Data Transfer)#

知識點 1:位址計算與 Byte Addressing#

觀念與公式#
  • 門牌邏輯: MIPS 是 Byte-addressable。1 個 Word = 4 Bytes。
  • 對齊限制 (Alignment): Word 的地址必須是 4 的倍數
  • 陣列偏移公式: Effective Address=Base Register+(Index×Element Size)\text{Effective Address} = \text{Base Register} + (\text{Index} \times \text{Element Size})
實戰演練#

Q:int Arr[7],其 Base Address 在 $s0 = 0x10008000。求 Arr[7] 的實際地址與 lw 指令。 Step-by-step:

  1. Offset=7×4=28\text{Offset} = 7 \times 4 = 28 (十進位)。
  2. 將 28 轉為十六進位:28=1×16+12    0x1C28 = 1 \times 16 + 12 \implies 0x1C
  3. 實際位址=0x10008000+0x1C=0x1000801C\text{實際位址} = 0x10008000 + 0x1C = 0x1000801C
  4. 指令:lw $t0, 28($s0)

知識點 2:資料傳輸指令 lw / sw#

觀念與公式#
  • lw (Load Word):Memory \rightarrow Register。
  • sw (Store Word):Register \rightarrow Memory。
  • 記憶口訣: lw 目的地在暫存器;sw 目的地在括號裡的記憶體。
實戰演練#

Q:翻譯 A[6] = B[3] + h; (s0=A,s1=B,s2=hs0=A, s1=B, s2=h) Step-by-step:

  1. lw $t0, 12($s1) # 讀取 B[3]B[3] (3×4=123 \times 4 = 12)
  2. add $t0, $t0, $s2 # B[3]+hB[3] + h
  3. sw $t0, 24($s0) # 寫回 A[6]A[6] (6×4=246 \times 4 = 24)

⚠️ 考前避坑指南:第 2 節#

  • 致命陷阱: 十進位與十六進位混淆。地址計算時,記得把 Offset (十進位) 轉成 Hex 再加。
  • 對齊錯誤: lw $t0, 3($s2) 會報錯,因為地址 3 不是 4 的倍數。

3. 指令格式與機器碼編譯#

知識點 1:R-Format 與 I-Format#

觀念與公式#
  • R-Format (暫存器型): 用於 add, sub, and 等。 [op:6 | rs:5 | rt:5 | rd:5 | shamt:5 | funct:6]
  • I-Format (立即值型): 用於 addi, lw, sw, beq 等。 [op:6 | rs:5 | rt:5 | immediate:16]
  • 暫存器編號: $t0$t7 = 8–15,$s0$s7 = 16–23。
實戰演練#

Q:將 sub $s1, $t2, $t0 轉為 Hex。(s1=17,t2=10,t0=8,op=0,funct=34s1=17, t2=10, t0=8, op=0, funct=34) Step-by-step:

  1. op=0, rs=10, rt=8, rd=17, shamt=0, funct=34
  2. 二進位:000000 01010 01000 10001 00000 100010
  3. 合併:0000 0001 0100 1000 1000 1000 0010 0010
  4. Hex:0x01488822

⚠️ 考前避坑指南:第 3 節#

  • 格式陷阱: 組語寫 add rd, rs, rt,但機器碼欄位是 rs, rt, rd目的地被挪到後面了!
  • 長度陷阱: I-format 的 immediate 只有 16 bits,範圍是 -32768 \sim 32767。

4. 控制流 (Branch & Jump)#

知識點 1:條件跳躍與 PC-Relative 定址#

觀念與公式#
  • 硬體設計: 分支指令使用「相對位址」以節省空間。
  • 核心公式: Target Address=(PC+4)+(Offset×4)\text{Target Address} = (\text{PC} + 4) + (\text{Offset} \times 4)
  • 計算 Offset 公式: Offset=Target(PC+4)4\text{Offset} = \frac{\text{Target} - (\text{PC} + 4)}{4}
實戰演練#

Q:bne $t0, $zero, Loop 位於 0x40Loop 位於 0x20。求 Offset。 Step-by-step:

  1. PC=0x40\text{PC} = 0x40PC+4=0x44\text{PC} + 4 = 0x44
  2. 位址差=0x200x44=0x24\text{位址差} = 0x20 - 0x44 = -0x24 (即十進位 -36)。
  3. Offset=36/4=9\text{Offset} = -36 / 4 = -9

知識點 2:Loop 與 If-Else 最佳化#

觀念與公式#
  • 反向邏輯: 為了跳過 code 塊,通常使用「相反的條件」來跳轉。
實戰演練#

Q:將 if (i != j) f = g + h; 優化。 A:

beq $s3, $s4, Exit # 若 i == j (反向條件) 則跳過
add $s0, $s1, $s2 # f = g + h
Exit:

⚠️ 考前避坑指南:第 4 節#

  • 最大盲點: 忘了 +4。Offset 是相對於「下一條指令」的距離!
  • 方向: 往回跳 (Loop) 的 Offset 必為負數;往下跳 (If) 為正數。

5. 副程式與堆疊管理 (Stack)#

知識點 1:函數呼叫契約 (jal / jr)#

觀念與公式#
  • jal (Jump and Link):存下回家的路到 $ra 並跳轉。
  • jr $ra (Jump Register):讀取 $ra 飛回家。
  • 暫存器約定: $a0$a3 傳參數;$v0$v1 傳回傳值。
  • J-Format (跳躍型):** 用於無條件長距離跳躍 j (Jump) 與 jal (Jump and Link)。 [op:6 | target address:26]

知識點 2:堆疊操作 (Push / Pop)#

觀念與公式#
  • Stack 特性:低位址 (Low Address) 生長。
  • Push (存檔): addi $sp, $sp, -4 接著 sw
  • Pop (還原): lw 接著 addi $sp, $sp, 4
實戰演練 (遞迴/非葉函數)#

Q:翻譯 res = func(a); return res + b; (a=$a0, b=$a1) A:

addi $sp, $sp, -8 # 騰空間
sw $ra, 4($sp) # 存 $ra (必存,因為 jal 會蓋掉它)
sw $a1, 0($sp) # 存 $a1 (因呼叫函數可能會弄髒它)
jal func
lw $a1, 0($sp) # 還原 b
lw $ra, 4($sp) # 還原回家地址
addi $sp, $sp, 8 # 歸還空間
add $v0, $v0, $a1 # res + b
jr $ra

⚠️ 考前避坑指南:第 5 節#

  • 致命失分: 呼叫別的函數前沒存 $ra。沒存 $ra 的遞迴會變成無限死迴圈。
  • 基底: 存取 Stack 永遠是用 0($sp)4($sp),基底暫存器絕對是 $sp

6. 大常數與定址模式#

知識點 1:32-bit 常數載入 (lui / ori)#

觀念與公式#
  • 兩步走: lui 載入高 16 位,ori 載入低 16 位。
實戰演練#

Q:載入 0x12345678 A:

  1. lui $s0, 0x1234 # $s0 = 0x12340000
  2. ori $s0, $s0, 0x5678 # $s0 = 0x12345678

知識點 2:五大定址模式總結#

模式意義範例
Immediate資料在指令裡addi
Register資料在暫存器add
BaseReg+Offset\text{Reg} + \text{Offset}lw, sw
PC-Relative(PC+4)+(Offset×4)(\text{PC}+4) + (\text{Offset} \times 4)beq, bne
PseudodirectPC高4位(指令26位2)\text{PC高4位} \parallel (\text{指令26位} \ll 2)j, jal

7. 程式生命週期 (Translation)#

核心流程與結構#

觀念與公式#
  • 流程: CCompilerASMAssemblerObjectLinkerExecLoaderMemory\text{C} \xrightarrow{\text{Compiler}} \text{ASM} \xrightarrow{\text{Assembler}} \text{Object} \xrightarrow{\text{Linker}} \text{Exec} \xrightarrow{\text{Loader}} \text{Memory}
  • Object Module 包含: Header, Text (Code), Data, Relocation Info, Symbol Table, Debug Info.
實戰演練#

Q:外部函數的名稱存放在哪?何時修正地址? A: 名稱存放在 Symbol Table;由 Linker 在 Relocation 階段修正地址。

⚠️ 考前避坑指南:第 7 節#

  • 排序陷阱: 先 Link (連結別人的 code) 產生 Exec,才能被 Load (載入) 到記憶體。
  • Relocation: 只有絕對地址需要 Relocation,相對地址 (beq) 不需 Linker 修正。

第三章:計算機算術與底層運算邏輯 (Computer Arithmetic)#

1. ALU 設計與基本算術運算#

核心觀念與公式#

  • ALU 基礎設計:算術邏輯單元 (ALU) 是 CPU 的計算大腦。為了支援多種運算 (Add, Sub, AND, OR, NOR, SLT),硬體設計採用「分而治之 (Divide and Conquer)」策略,先設計 1-bit ALU,再串聯成 32-bit ALU。
  • 減法實作訣竅 (2’s Complement):利用「取補數加一」將減法轉換為加法。硬體上會將 B 輸入反轉 (Bnegate),並將最低位的進位輸入設為 1 (Cin=1C_{in} = 1)。

AB=A+B+1A - B = A + B' + 1

  • 溢位偵測 (Overflow Detection):當兩個「同號」數字相加,結果卻出現「異號」時即發生溢位。硬體判斷公式為最高位元的進位輸入與進位輸出做 XOR:

Overflow=Cin[N1]Cout[N1]\text{Overflow} = C_{in}[N-1] \oplus C_{out}[N-1]

  • 零偵測 (Zero Detection):將 ALU 輸出的所有 32 個位元接上一個巨大的 NOR Gate。只有全為 0 時才輸出 1(支援分支指令 beq)。

📝 實戰演練:判斷運算是否發生溢位 (Overflow)#

經典考題: 給定 4-bit 系統,範圍為 87-8 \sim 7,請計算 7+37 + 345-4 - 5,並判斷硬體如何抓出溢位?

【解析】#

第一步:計算 7+37 + 3

  • 二進位011120111_2 (7) + 001120011_2 (3)
  • 運算過程:相加後得到 101021010_2
  • 判定:正數加正數,符號位變成 1(負數,數值為 -6),發生溢位!
  • 硬體檢驗:最高位 (MSB) 的 Cin=1C_{in} = 1Cout=0C_{out} = 010=11 \oplus 0 = 1 (Overflow 成立)。

第二步:計算 45-4 - 5

  • 二進位110021100_2 (-4) + 101121011_2 (-5)
  • 運算過程:相加得到 (1)01112(1)0111_2
  • 判定:負數加負數,符號位變成 0(正數,數值為 7),發生溢位!
  • 硬體檢驗:最高位 (MSB) 的 Cin=0C_{in} = 0Cout=1C_{out} = 101=10 \oplus 1 = 1 (Overflow 成立)。

2. 快速加法器 (Fast Adders - CLA)#

核心觀念與公式#

  • 直觀意義:傳統的漣波進位加法器 (Ripple Carry Adder) 必須等前一個位元算出進位 (CoutC_{out}) 才能算下一個,延遲太高(O(N)O(N))。前瞻進位加法器 (Carry Look-ahead Adder, CLA) 透過數學展開,讓各個位元的進位可以「同時/提早」算出來。
  • 產生進位 (Generate):該位元本身相加就會產生進位。

gi=AiBig_i = A_i \cdot B_i

  • 傳遞進位 (Propagate):只要有低位的進位送上來,該位元就能幫忙傳遞下去。

pi=Ai+Bi(或 AiBi)p_i = A_i + B_i \quad \text{(或 } A_i \oplus B_i \text{)}

  • 進位計算通式

Ci+1=gi+piCiC_{i+1} = g_i + p_i \cdot C_i


📝 實戰演練:展開 CLA 的進位方程式#

經典考題: 請利用 gig_ipip_i 寫出 C1,C2,C3C_1, C_2, C_3 的前瞻進位邏輯方程式,並說明其物理意義。

【解析】#
  1. 第一階 (C1C_1)C1=g0+(p0C0)C_1 = g_0 + (p_0 \cdot C_0)
  2. 第二階 (C2C_2):將 C1C_1 帶入 C2=g1+p1C1C_2 = g_1 + p_1 \cdot C_1
  • 展開得:C2=g1+(p1g0)+(p1p0C0)C_2 = g_1 + (p_1 \cdot g_0) + (p_1 \cdot p_0 \cdot C_0)
  1. 第三階 (C3C_3):將 C2C_2 帶入 C3=g2+p2C2C_3 = g_2 + p_2 \cdot C_2
  • 展開得:C3=g2+(p2g1)+(p2p1g0)+(p2p1p0C0)C_3 = g_2 + (p_2 \cdot g_1) + (p_2 \cdot p_1 \cdot g_0) + (p_2 \cdot p_1 \cdot p_0 \cdot C_0)

物理意義C3C_3 會產生 1,代表要麼是在 Bit 2 產生進位 (g2g_2);要麼是在 Bit 1 產生並由 Bit 2 傳遞 (p2g1p_2 \cdot g_1);或者是更低階產生並一路暢通傳遞上來。所有因子都不依賴先前的 Carry 結果,可以直接從 A 與 B 的輸入訊號平行算出!


3. 乘法器與 Booth’s Algorithm#

核心觀念與操作規則#

  • 直觀意義:二進位乘法本質上就是「判斷是否要加上被乘數」再「平移」。為了節省硬體,我們將一開始的 64-bit ALU 縮減為 32-bit ALU,並把「乘數」塞進「乘積 (Product)」暫存器的右半邊。
  • Booth’s Algorithm (有號數乘法捷徑):遇到一長串的 1(例如 011112=1501111_2 = 15),與其做四次加法,不如把它當作 10000200001210000_2 - 00001_2 (16 - 1),只需一次減法與一次加法。
  • 算術右移 (Arithmetic Right Shift):運算後,Product 暫存器必須做算術右移,也就是保留符號位

Booth 操作規則表(觀察當前位元 xix_i 與右側位元 xi1x_{i-1}):

當前位元 (xix_i)右側位元 (xi1x_{i-1})區段狀態執行動作
00連續 0 區段的中央不做事 (None)
01連續 1 區段的結束加被乘數 (Add)
10連續 1 區段的開始減被乘數 (Sub)
11連續 1 區段的中央不做事 (None)

image
image

📝 實戰演練:Booth’s Algorithm 實作#

經典考題: 使用 Booth 演算法計算 2×(3)2 \times (-3)。已知被乘數 (Multiplicand) 為 001020010_2 (2),乘數 (Multiplier) 為 110121101_2 (-3)。

【解析】#

被乘數 M=00102M = 0010_2 (2),M=11102-M = 1110_2 (-2)。 初始狀態:左半部補 0,右半部放乘數,最右方補一個隱藏位元 0 \to 0000 1101 0

  1. Step 1:看末兩位 10 \to 代表 1 的開始,執行減法 (加上 M-M)。
  • 左半部 0000 + 1110 = 1110 \to Product 變為 1110 1101 0
  • 算術右移 1 bit \to 1111 0110 1
  1. Step 2:看末兩位 01 \to 代表 1 的結束,執行加法 (加上 MM)。
  • 左半部 1111 + 0010 = 0001 \to Product 變為 0001 0110 1
  • 算術右移 1 bit \to 0000 1011 0
  1. Step 3:看末兩位 10 \to 執行減法 (加上 M-M)。
  • 左半部 0000 + 1110 = 1110 \to Product 變為 1110 1011 0
  • 算術右移 1 bit \to 1111 0101 1
  1. Step 4:看末兩位 11 \to 不做事 (None)。
  • 算術右移 1 bit \to 1111 1010 1

結論:結束循環,捨棄最後一個隱藏位元。最終答案前 8 bits 為 1111 1010,轉換為十進位即為 6-6。完全正確!


4. 除法器演算法 (Division Algorithm)#

核心觀念與演算法#

  • 直觀意義:除法硬體是將「被除數」放在 Remainder(餘數暫存器)中,不斷往左位移,試圖去減掉 Divisor(除數)。減得過,商數補 1;減不過,商數補 0,並把減掉的加回來(Restore)。
  • 最佳化版本硬體 (Version 2):只需要 32-bit ALU 與 32-bit 除數暫存器。商數與餘數共用一個 64-bit 的 Remainder 暫存器(隨著左移,右邊空出來的位元剛好用來放 Quotient 商數)。
    image
    image

📝 實戰演練:除法器最佳化演算法 (Version 2)#

經典考題: 以無號數除法計算 7÷27 \div 2 (即 01112/001020111_2 / 0010_2),請追蹤 Remainder 暫存器前兩步的變化。

【解析】#

初始狀態:Divisor = 0010,Remainder = 0000 0111

  1. Iteration 1:
  • Remainder 左移 1 bit \to 0000 1110
  • 左半部減去 Divisor (0000 - 0010 = 1110,小於 0) \to 1110 1110
  • 發現小於 0:還原 (Restore) 加回 0010,變成 0000 1110,然後左移並將最低位置 0 (實際上是將 LSB 設為 0) \to 0001 1100
  1. Iteration 2:
  • 若減完 0\ge 0,就不須還原,且把商的位元設為 1 (依此類推)。
  • 最終 Remainder 的左半部是真餘數 0001 (1),右半部是商數 0011 (3)。

5. 浮點數 IEEE 754 格式#

核心觀念與結構#

  • 直觀意義:浮點數就像是二進位版的「科學記號」,用來儲存極大、極小或小數。

IEEE 754 單精度 (Single Precision, 32-bit) 結構

欄位位元數定義與功能
Sign (S)1-bit0 為正,1 為負。
Exponent (E)8-bit表示指數。採用「偏差值 (Biased)」表示法,Bias = 127。實際指數 y=E127y = E - 127
Significand (F)23-bit小數點後的值。為了省空間,對於正規劃數字,預設小數點前面必定有一個隱藏的 1.

還原公式

Value=(1)S×(1.F)2×2(E127)\text{Value} = (-1)^S \times (1.F)_2 \times 2^{(E - 127)}


📝 實戰演練:十進位轉 IEEE 754 浮點數#

經典考題一 (基礎): 將十進位 0.75-0.75 轉換為單精度 IEEE 754 格式。

【解析】#
  1. Sign:負數,所以 S=1S = 1
  2. 轉換為二進位科學記號
  • 0.75×2=1.50.75 \times 2 = 1.5 (取 1)
  • 0.5×2=1.00.5 \times 2 = 1.0 (取 1)
  • 科學記號表示法:0.112×20=1.12×21-0.11_2 \times 2^0 = -1.1_2 \times 2^{-1} (正規化,將 1 移到小數點前)
  1. 計算 Exponent
  • 實際指數為 1-1。加上 Bias 127:E=1+127=126E = -1 + 127 = 126
  • 126 的二進位:0111 1110
  1. 計算 Fraction (Significand)
  • 取小數點後面的部分:1。補滿 23 bits:100 0000 0000 0000 0000 0000
  1. 組合1 01111110 10000000000000000000000

經典考題二 (進階): 將無限循環小數 1/31/3 轉換為單精度 IEEE 754 格式。

【解析】#
  1. 1/3=0.333333101/3 = 0.333333_{10}。不斷乘以 2 取整數部分,得到二進位小數為 0.01010101...20.01010101..._2
  2. 正規化:0.010101...×20=1.010101...×220.010101... \times 2^0 = 1.010101... \times 2^{-2}
  3. S=0S = 0
  4. E=2+127=12510=011111012E = -2 + 127 = 125_{10} = 0111 1101_2
  5. Fraction = 0101 0101 0101 0101 0101 010 (截斷至 23 位)。

6. 浮點數的極限與運算#

特殊數值與運算步驟#

特殊數值 (Special Numbers) 辨析表

數值類型Exponent (E)Fraction (F)意義與用途
000包含 +0+00-0
Denorm00\neq 0非正規化數。用於表示極小的數字,無隱藏的 1.,公式為 0.F×21260.F \times 2^{-126}
Infinity (\infty)2550用來表示除以零等極端狀況。
NaN2550\neq 0Not a Number。例如 0/00/04\sqrt{-4}

浮點數加法步驟

  1. 對齊小數點:將指數較小的數字向右移,使其指數與較大的數字相同。
  2. 尾數相加:Mantissa 相加。
  3. 正規化結果:並檢查 Overflow / Underflow。
  4. 捨入 (Rounding):必要時再次正規化。

📝 實戰演練:浮點數加法流程#

經典考題: 計算 1.0002×21+(1.1102×22)1.000_2 \times 2^{-1} + (-1.110_2 \times 2^{-2}),也就是十進位的 0.5+(0.4375)0.5 + (-0.4375)

【解析】#
  1. 對齊小數點 (Align binary points)1>2-1 > -2,所以要把較小的數字的指數變成 1-11.1102×22-1.110_2 \times 2^{-2} 右移變成 0.1112×21-0.111_2 \times 2^{-1}
  2. 尾數相加 (Add mantissa)1.0002+(0.1112)=0.00121.000_2 + (-0.111_2) = 0.001_2。目前結果為 0.0012×210.001_2 \times 2^{-1}
  3. 正規化 (Normalize): 向左移 3 位,指數減 3:1.0002×241.000_2 \times 2^{-4}。沒有 Over/Underflow。
  4. 捨入 (Rounding)1.0002×241.000_2 \times 2^{-4} 不需更改。此即十進位的 0.06250.0625 (0.50.4375=0.06250.5 - 0.4375 = 0.0625),正確。

7. 補充#

  1. 溢位 (Overflow) 與進位 (Carry) 絕對不能混為一談:無號數 (Unsigned) 看的是 CoutC_{out};有號數 (2’s Complement) 看的是 CinCoutC_{in} \oplus C_{out}。兩個負數相加產生 CoutC_{out} 不代表溢位,除非符號變正。
  2. Booth’s Algorithm 的陷阱:在算術右移 (Arithmetic Right Shift) 時,最高位元(MSB) 必須複製保留自己原本的符號位,千萬不要補 0!另外,初始值最右邊補上的隱含位元固定為 0,第一回合比較一定是看「乘數的 LSB」與「這個補上的 0」。
  3. IEEE 754 偏置 (Biased) 的意義:指數欄位不是使用 2 的補數表示法!使用 Biased 表示是為了讓浮點數能夠像一般整數一樣,直接用原本的 Integer ALU 進行大小比對,硬體設計更簡單。
  4. 浮點數運算「不具」結合律 (Not Associative):程式考題常愛問 (x+y)+z(x + y) + z 是否等於 x+(y+z)x + (y + z)?答案是!因為非常大的數字加非常小的數字(如 1.5×1038+1.01.5 \times 10^{38} + 1.0)時,小的數字在對齊小數點右移時會直接被捨去。順序不同,捨去誤差就不同。
  5. 減法器設計細節:將 ALU 轉為減法模式時,控制訊號不能只翻轉 B (Bnegate),一定要記得把 CinC_{in} 設為 1 (完成二的補數中 “+1” 的動作),這是考題最常挖洞漏寫的點。

第四章:單週期處理器設計與控制邏輯#

1. 處理器設計的五大核心步驟與時脈準則#

核心觀念辨析#

  • 生活比喻 / 直觀意義:設計一個處理器就像蓋一座全自動化工廠。
  1. 首先要調查這座工廠要生產什麼產品(分析指令集,看支援哪些運算)。
  2. 決定工廠內部的基本機器與「工作節拍的標準」(選擇元件與建立時脈準則)。
  3. 將機器用水管、傳送帶連接起來(組裝資料路徑)。
  4. 調查每種產品生產時哪些閥門要開、哪些開關要關(分析每條指令的控制點)。
  5. 建造一間中央控制室自動控管這些開關(組裝控制邏輯)。
  • 必背核心步驟(五部曲)
  1. Analyze instruction set:分析指令集,透過暫存器轉換(Register Transfers)定義指令含意。
  2. Select components & Establish clocking methodology:選擇資料路徑元件,建立時脈控制方法。
  3. Assemble datapath:組裝符合暫存器轉換需求的資料路徑。
  4. Analyze control points:分析每條指令的執行,決定控制信號的設定值。
  5. Assemble the control logic:組裝整體的控制邏輯(包含 Main Control 與 Local Control)。
  • 時脈準則(Clocking Methodology)口訣: 🗣️ 「同一個週期內:邊緣讀出、路徑運算、邊緣寫回,絕不打結!」 訊號在一條路徑上由狀態元件(如暫存器)出發,經過組合邏輯電路轉換,最後在下一個時脈上升緣(Clock Edge)存入另一個(或同一個)狀態元件。單週期不允許出現單一週期內部的硬體邏輯無窮回授(No feedback within a single cycle)。

📝 實戰演練:訊號衝突與時序行為#

經典考題 1:(段考常考頻率:⭐⭐⭐) 在單週期處理器中,若某暫存器 R1R_1 在同一個時脈週期內,既被讀取(Read)其數值,又將運算後的新結果寫回(Write)同一暫存器 R1R_1,這是否會造成訊號衝突或產生內部的邏輯無窮迴圈?請詳述原因。

【解析】#
  • Step 1(核心觀念):這在單週期架構下是完全允許且不會造成衝突的。
  • Step 2(時序行為):單週期架構採用的是邊緣觸發(Edge-triggered)機制。當一個時脈週期的上升緣到達時,暫存器 R1R_1 內部原本穩定的舊資料會被讀出到輸出端線路上。接著,這個舊資料會通過外部的組合邏輯電路(如 ALU)進行運算,並在該時脈週期中持續往後傳遞,最後到達暫存器 R1R_1 的輸入端。此時,輸入端的新資料只要在下一個時脈上升緣到來之前保持穩定,就會在下一個上升緣被鎖存(Write)進暫存器中。
  • Step 3(結論):由於讀出的是「舊值」,寫入的是「新值」,且寫入動作要等到週期末端的下一個時脈邊緣才會發生,因此在同一個時脈週期內,讀出後又寫回同一個暫存器並不會造成干擾或回授。

💡 補充變化考法 若考試改問「若是電平觸發(Level-sensitive)而不是邊緣觸發會發生什麼事?」 答案是:暫存器在整個高電平期間皆具備穿透性,只要時脈訊號一直維持在高電平,輸出與輸入就會產生不間斷的即時回授,導致訊號進入無法預測的震盪與數據破壞狀態。


2. 基本硬體元件與狀態更新邏輯 (組合 vs 序向)#

物理意義與直觀辨析#

  1. 組合邏輯元件 (Combinational Elements):就像「算盤」或「沒有記憶的水管」。你輸入什麼,它就立刻根據功能輸出什麼,輸出只跟目前的輸入有關,不保存任何過去的痕跡。
  2. 序向 / 狀態元件 (Sequential / State Elements):就像「筆記本」或「蓄水池」。它們可以鎖住並存儲資訊,輸出與過去儲存的狀態有關。狀態元件的更新必須由時脈訊號(Clock Signal)來控制主導。

核心元件分類與時脈依賴表#

元件名稱類型讀寫控制與時脈依賴度
AND 閘 / 加法器 (Adder)組合邏輯無時脈,隨輸入改變而立刻改變輸出。
多工器 (MUX) / ALU組合邏輯無時脈,依據選擇訊號/控制碼決定輸出。
暫存器 (Register)序向邏輯邊緣觸發。若有 Write Enable 訊號,當其為 1 且時脈邊緣觸發時才更新。
暫存器檔案 (Register File)混合結構讀取 (Read):如同組合邏輯(給予暫存器編號即刻輸出資料)。
記憶體 (Ideal Memory)混合結構讀取:如同組合邏輯(給定地址,經過存取時間後直接輸出,無需讀取控制)。

📝 實戰演練:暫存器檔案讀寫機制#

經典考題 2:(段考常考頻率:⭐⭐⭐⭐) 關於 MIPS 的暫存器檔案(Register File),下列敘述何者正確? (A) 讀取暫存器與寫入暫存器皆需要在時脈邊緣觸發。 (B) 讀取暫存器不依賴時脈,其行為如同組合邏輯電路;寫入則需要時脈邊緣配合寫入使能(Write Enable)。 [C] 暫存器檔案擁有兩個 32-bit 的輸入埠以及一個 32-bit 的輸出埠。 (D) 當寫入使能訊號為 0 時,暫存器的輸出會變為 0。

【解析】#
  • (A) 錯誤:讀取時如同組合邏輯行為,給定編號即輸出,不需要時脈邊緣觸發。
  • (B) 正確:讀取是組合電路行為,寫入必須在時脈邊緣抵達且 Write Enable = 1 時才會發生。
  • [C] 錯誤:擁有兩個 32-bit 的輸出埠(busA, busB)以及一個 32-bit 的輸入埠(busW)。
  • (D) 錯誤:當 Write Enable = 0 時,暫存器內數值保持不變,輸出端依然輸出原本鎖存的內容,不會變成 0。
  • 答案:選 (B)

💡 補充變化考法 考試常結合微架構圖問:「記憶體(Memory)的 Read 控制訊號在單週期中是否為必須?」 答案是:在理想單週期中,記憶體讀取被視為組合邏輯,傳入有效 Address 後 Data Out 隨後即有效,因此不需要讀取控制訊號(No need for read control)。


3. 指令集微架構分析與資料路徑 (Datapath) 的組裝#

直觀物理意義#

  • 資料路徑是指令在 CPU 內部跑動的「物理軌道」。必須為每種類型的指令規劃專屬軌道,並利用多工器(MUX)切換,避免訊號直接接在一起而打架。

MIPS 指令格式與暫存器轉換公式統整#

  1. R-Type (如 add, sub, and, or, slt)
  • 格式op(6) | rs(5) | rt(5) | rd(5) | shamt(5) | funct(6)
  • 暫存器轉換

R[rd]R[rs] op R[rt];PCPC+4R[\text{rd}] \leftarrow R[\text{rs}] \text{ op } R[\text{rt}]; \quad \text{PC} \leftarrow \text{PC} + 4

  1. I-Type - Load (lw rt, rs, imm16)
  • 格式op(6) | rs(5) | rt(5) | immediate(16)
  • 暫存器轉換

R[rt]Mem[R[rs]+SignExt(imm16)];PCPC+4R[\text{rt}] \leftarrow \text{Mem}[R[\text{rs}] + \text{SignExt}(\text{imm16})]; \quad \text{PC} \leftarrow \text{PC} + 4

  1. I-Type - Store (sw rt, rs, imm16)
  • 格式op(6) | rs(5) | rt(5) | immediate(16)
  • 暫存器轉換

Mem[R[rs]+SignExt(imm16)]R[rt];PCPC+4\text{Mem}[R[\text{rs}] + \text{SignExt}(\text{imm16})] \leftarrow R[\text{rt}]; \quad \text{PC} \leftarrow \text{PC} + 4

  1. I-Type - Branch (beq rs, rt, imm16)
  • 暫存器轉換

if (R[rs]==R[rt])PC(PC+4)+(SignExt(imm16)×4)elsePCPC+4\text{if } (R[\text{rs}] == R[\text{rt}]) \quad \text{PC} \leftarrow (\text{PC} + 4) + (\text{SignExt}(\text{imm16}) \times 4) \quad \text{else} \quad \text{PC} \leftarrow \text{PC} + 4

  1. J-Type - Jump (j target)
  • 格式op(6) | target_address(26)
  • 暫存器轉換

PC(PC+4)[31:28]  (target_address×4)\text{PC} \leftarrow (\text{PC}+4)[31:28] \ \Vert \ (\text{target\_address} \times 4)


📝 實戰演練:Branch 指令位移計算#

經典考題 3:(段考常考頻率:⭐⭐⭐⭐⭐) 請說明在 MIPS 單週期架構中,為什麼 beq 指令在計算分支目標地址時,需要將 16 位的立即數先進行「符號擴充(Sign Extend)」再「左移 2 位(Shift left 2)」?最後又是如何與 PC 結合的?

【解析】#
  • Step 1(符號擴充的必要性):MIPS 立即數欄位只有 16 位元,但 CPU 內部資料路徑與主記憶體定址皆為 32 位元。為了支援正向與負向的分支偏移植,必須透過符號擴充將 16 位元填滿至 32 位元,維持正負號實質意義。
  • Step 2(左移 2 位的物理意義):MIPS 架構採用字組對齊(Word Alignment),每條指令長度固定為 4 Bytes,因此記憶體起始地址最後兩個位元固定是 00。為了擴大跳躍範圍,立即數儲存的是「指令條數偏移量」。將其乘以 4(左移 2 位),就能還原為真實的位元組偏移量(Byte Offset),使跳躍能力擴大 4 倍。
  • Step 3(與 PC 結合):分支目標地址是相對於下一條指令的地址(PC+4\text{PC}+4)進行偏移計算。公式為:

Branch Target Address=(PC+4)+(SignExt(imm16)×4)\text{Branch Target Address} = (\text{PC} + 4) + (\text{SignExt}(\text{imm16}) \times 4)

💡 補充變化考法 若考試考全新的指令,例如 bne(不相等時跳躍),其資料路徑與 beq 完全相同,唯一差別在於控制邏輯中,判斷 PC 軌道多工器切換的條件由 ALU Zero = 1 變成了 ALU Zero = 0。


4. 單週期控制單元與真值表設計 (Main Control & ALU Control)#

核心觀念辨析#

  • 生活比喻:控制單元就是處理器的「大腦和神經系統」。
  • 主控制器 (Main Control):看一眼指令的 Opcode(前 6 位元),發出宏觀控制訊號(例如:要不要寫入暫存器?要不要讀寫記憶體?)。
  • ALU 控制器 (ALU Control):地方局部控制器。當主控制器判定為 R-type 時,給 ALU 控制器丟暗號 ALUOp = 10;ALU 控制器再去細看指令末尾的 funct 欄位(後 6 位元),精準調校出 ALU 該做加法、減法、AND 還是 OR。

控制信號物理意義一覽#

  • RegDst:寫回暫存器的目標編號是 rt 欄位(0)還是 rd 欄位(1)。
  • ALUSrc:ALU 第二個輸入端來自暫存器數據(0)還是擴充後的立即數(1)。
  • MemtoReg:寫回暫存器檔案的資料來自 ALU 計算結果(0)還是 Data Memory 讀出的資料(1)。
  • RegWrite:是否允許在時脈邊緣將資料寫入暫存器檔案(1 允許,0 禁止)。
  • MemRead / MemWrite:主記憶體的讀取 / 寫入使能控制訊號。
  • Branch:是否為分支指令(與 ALU 的 Zero 訊號做運算,決定 PC 軌道的切換)。

🔥 必背!控制信號完整全真值表#

(註:真值表依據典型微架構設計標準彙整,X 代表 Don’t Care)

指令OpcodeRegDstALUSrcMemtoRegRegWriteMemReadMemWriteBranchALUOp
R-type000000100100010
lw100011011110000
sw101011X1X001000
beq000100X0X000101

📝 實戰演練:Stuck-at 錯誤分析#

經典考題 4:(段考常考頻率:⭐⭐⭐⭐⭐) 假設單週期處理器中,主控制器的控制線路發生硬體故障,導致 MemtoReg 訊號線路永久斷路並卡在固定的訊號值 0(Stuck-at-0 錯誤)。請問在此故障下,哪些指令依然能夠正常執行?哪些指令會發生錯誤?

【解析】#
  • Step 1(定位錯誤意義):MemtoReg = 0 代表寫回暫存器檔案的 MUX 永久鎖定在「選擇 ALU 運算結果」通道。

  • Step 2(逐一檢視指令)

  • R-type 指令:本就要求 MemtoReg = 0,故障值與期望值相符,正常執行。

  • Store (sw):不寫回暫存器,RegWrite = 0。MUX 切到哪都沒差,正常執行。

  • Branch (beq):同上,RegWrite = 0,正常執行。

  • Load (lw):正常需設定 MemtoReg = 1。卡在 0 會導致寫回暫存器的資料變成「ALU 算出的記憶體地址」,而非真實數據,因此發生錯誤。

  • Step 3(結論)

  • 正常執行:R-type, sw, beq。

  • 發生錯誤:lw。

💡 補充變化考法 如果是 RegWrite 發生 Stuck-at-0 錯誤呢?答案是所有需要修改暫存器內容的指令(R-type, lw)全部報銷,只有 sw 與 beq 能存活。這類 Stuck-at 題型是各大資工所必考!


5. 關鍵路徑 (Critical Path) 時序計算與單週期缺陷#

核心觀念辨析#

  • 木桶理論:單週期處理器的時脈週期時間(TcT_c),取決於耗時最長(最慢)的那條指令之總延遲。
  • 最耗時指令分析lw(Load Word)是公認的大魔王。它必須走完所有部門:拿 PC \rightarrow 翻指令記憶體 \rightarrow 讀暫存器檔案 \rightarrow 跑 ALU 算地址 \rightarrow 翻數據記憶體 \rightarrow 走多工器寫回暫存器。

關鍵路徑公式 (lwlw 延遲公式)#

TcTclk-to-q+TI-Mem+TRegRead+TALU+TD-Mem+TMUX+TSetupT_c \ge T_{\text{clk-to-q}} + T_{\text{I-Mem}} + T_{\text{RegRead}} + T_{\text{ALU}} + T_{\text{D-Mem}} + T_{\text{MUX}} + T_{\text{Setup}}

單週期設計的致命弱點 (Drawback of Single-Cycle)#

  • 時脈週期長,效率極低:時脈週期必須去遷就最慢的 lw。即使是執行極快、不需存取記憶體的指令(如 add, beq),也被迫等待一樣長的時間,白白浪費 CPU 資源。

📝 實戰演練:時鐘週期與閒置時間計算#

經典考題 5:(段考常考頻率:⭐⭐⭐⭐⭐) 假設某處理器元件延遲如下:

  • 指令記憶體 (TI-MemT_{\text{I-Mem}}):250 ps

  • 資料記憶體 (TD-MemT_{\text{D-Mem}}):300 ps

  • 暫存器讀取/寫入 (TRegT_{\text{Reg}}):150 ps

  • ALU 運算 (TALUT_{\text{ALU}}):200 ps

  • 多工器 (TMUXT_{\text{MUX}}):30 ps 請計算最小時脈週期時間與最高主頻。若有一條 add 指令,它實際只需多少時間?會被分配多少時間?帶來什麼缺點?

【解析】#
  • Step 1(最差時序路徑): 代入 lw 路徑:Fetch \rightarrow RegRead \rightarrow MUX \rightarrow ALU \rightarrow D-Mem \rightarrow MUX \rightarrow RegWrite。

Tc=250 ps+150 ps+30 ps+200 ps+300 ps+30 ps+150 psT_c = 250\text{ ps} + 150\text{ ps} + 30\text{ ps} + 200\text{ ps} + 300\text{ ps} + 30\text{ ps} + 150\text{ ps}

Tc=1110 ps=1.11 nsT_c = 1110\text{ ps} = 1.11\text{ ns}

最高主頻:

f=1Tc=11.11×109 s900.9 MHzf = \frac{1}{T_c} = \frac{1}{1.11 \times 10^{-9}\text{ s}} \approx 900.9\text{ MHz}

  • Step 2(add 指令時間分析)

  • add 實際路徑:Fetch (250 ps) \rightarrow RegRead (150 ps) \rightarrow MUX (30 ps) \rightarrow ALU (200 ps) \rightarrow MUX (30 ps) \rightarrow RegWrite (150 ps)。

  • 實際所需時間 = 810 ps。

  • 被分配時間:強行分配 1110 ps。

  • Step 3(缺點總結): 這導致 add 指令在 810 ps 時就做完事情了,但在接下來的 300 ps 內,整個硬體電路只能處於閒置狀態,浪費晶片效能。


6. 補充#

  1. J-type 立即數左移位元陷阱:計算 Jump 指令目標地址時,target 欄位只有 26 位元。左移 2 位變成 28 位元後,剩下最高的 4 位元是直接借用 (PC+4)(\text{PC}+4) 的最高 4 位元,千萬別誤寫成全部補 0。
  2. 多工器 (MUX) 訊號選擇張冠李戴
  • RegDst = 1 時,目標是寫入 rd(第 11-15 位元);為 0 時寫入 rt(第 16-20 位元)。
  • MemtoReg = 1 時,選取的是記憶體(Memory);為 0 時選取的是 ALU 結果。
  1. 暫存器檔案讀寫時序混淆:切記「讀是組合、寫是序向」!在計算時序關鍵路徑(Critical Path)時,讀取時間(RegRead)發生在週期前半段,寫回建立時間(Setup Time)發生在末尾,兩者必須分別計入公式,不可混為一談。

第五章:管線化處理器架構與資料路徑 (Pipelining)#

1. 管線化基礎與效能度量 (Pipelining Basics)#

觀念與公式#

  • 直觀意義:如同自助洗衣店的「洗衣服 (Laundry)」過程 (洗、烘、摺)。若循序執行,每個人都要等前一個人全部做完才能開始,極度沒效率。管線化就是「只要機器 (硬體資源) 一空出來,下一道指令立刻無縫接軌」。
  • 物理意義:管線化無法減少「單一指令的執行時間 (Latency)」,但能大幅提升「整體系統的吞吐量 (Throughput)」。管線的最高速率受限於「最慢的那個管線階段 (Pipeline Stage)」。
  • 必背公式
    • Potential Speedup=Number of pipe stages\text{Potential Speedup} = \text{Number of pipe stages} (理想加速倍率 = 管線階數)
    • Tpipeline=Tsingle_cycleNumber of stagesT_{pipeline} = \frac{T_{single\_cycle}}{\text{Number of stages}}
    • NN 個指令的總執行時間 = (Stages+N1)×Cycle Time(\text{Stages} + N - 1) \times \text{Cycle Time}

實戰演練(題型大全)#

[題型 1: Single-cycle vs. Pipeline Performance]

  • 題目:假設 Single-cycle 的 Tc=800psT_c = 800ps,切分為 IF, ID, EX, MEM, WB 五個階段,各耗時 200ps。請求出連續執行 3 個 lw 指令在 Single-cycle 與 Pipelined 架構下的總耗時。
  • Step-by-step 解答
    1. Single-cycle:每個 lw 獨佔整個 Datapath,需 800ps800ps。3 個 lw =3×800=2400ps= 3 \times 800 = 2400ps
    2. Pipelined:時脈週期 TcT_c 決定於最慢的階段,即 200ps200ps
    3. 利用公式:時間 =(5+31)×200ps=7×200ps=1400ps= (5 + 3 - 1) \times 200ps = 7 \times 200ps = 1400ps
  • 常考頻率:★★★★☆
  • 重要程度:★★★★☆ (期中考極愛考這類計算,若考題加上不平均的 stage times,請務必挑「最慢的 stage」作為 TcT_c)

2. 五級管線化資料路徑 (5-Stage Pipelined Datapath)#

觀念與公式#

  • 直觀意義:把 CPU 切成五個分工明確的部門,並在部門之間設立「收發匣 (Pipeline Registers)」。
  • 核心知識點
    1. IF (Instruction Fetch):透過 PC 拿指令,並計算 PC+4PC+4
    2. ID (Instruction Decode):解碼指令,從暫存器檔案 (Register File) 讀取資料。
    3. EX (Execution):ALU 執行運算或計算記憶體位址。
    4. MEM (Memory Access):對 Data Memory 進行讀/寫。
    5. WB (Write Back):將結果寫回 Register File。
  • 捷徑口訣:資料只能「往前流」,唯一倒流的機會只有 Write Back (寫回 Register) 以及 PC 的更新。每個階段間的 Latches 分別為 IF/ID, ID/EX, EX/MEM, MEM/WB

實戰演練(題型大全)#

[題型 2: 管線化狀態追蹤 (Pipeline Registers Tracking)]

  • 題目:給定指令序列 lw $10, 20($1) 緊接著 sub $11, $2, $3,請問在 Clock 4 時,各個 Pipeline Registers 裡面存著什麼?
  • Step-by-step 解答
    1. 推導時間軸:lw 在 Clock 1 進 IF,Clock 4 會抵達 MEMsub 在 Clock 2 進 IF,Clock 4 抵達 EX
    2. EX/MEM Latch (屬於 lw 的產出):儲存 ALU 算出的位址 (20 + \1)以及準備寫入暫存器的目標編號() 以及準備寫入暫存器的目標編號 (`10`)。
    3. ID/EX Latch (屬於 sub 的產出):儲存 $2$3 的值,以及 ALUOp 設為 sub 等控制訊號。
  • 常考頻率:★★★☆☆
  • 重要程度:★★★☆☆ (通常配合作圖題考出,確認你是否知道每個 Stage 當下在做什麼)

3. 資料危險與解法 (Data Hazards: Forwarding & Stalling)#

觀念與公式#

  • 直觀意義:學弟 (後面的指令) 需要學長 (前面的指令) 的筆記 (運算結果),但學長還沒把筆記寫進資料庫 (Register File)。
  • Data Hazard 分類:在 MIPS 5-stage 中,主要且唯一會發生的是 RAW (Read After Write)。WAR 與 WAW 均不會發生 (因為永遠在 Stage 2 讀,Stage 5 寫)。
  • 解法 1:Forwarding (Bypassing)
    • 直接從 EX/MEM (剛算完) 或 MEM/WB (剛讀完) 把資料「抄捷徑」導回 ALU 輸入端。
    • EX Hazard 條件EX/MEM.RegWriteEX/MEM.RegRd != 0EX/MEM.RegRd == ID/EX.RegRs (或 RegRt)。
    • MEM Hazard 條件MEM/WB.RegWriteMEM/WB.RegRd != 0MEM/WB.RegRd == ID/EX.RegRs (或 RegRt)。
  • 解法 2:Stalling (Load-Use Hazard)
    • 當前一個指令是 lw,而下一個指令立刻需要它的值,此時就算 Forwarding 也來不及 (因為 MEM 階段才拿到資料,但下一步的 EX 已經要用了)。
    • Stall 條件ID/EX.MemRead(ID/EX.RegisterRt == IF/ID.RegisterRs)(ID/EX.RegisterRt == IF/ID.RegisterRt)
    • 處理方式:塞入一個 Bubble (NOP),凍結 PC 與 IF/ID 一週期。

實戰演練(題型大全)#

[題型 3: 找尋所有 Data Hazards 並畫出 Forwarding 路徑]

  • 題目:給定以下指令序列,指出哪些地方發生 Hazard,並說明由哪個 Forwarding Unit 解決。
    1. sub $2, $1, $3
    2. and $12, $2, $5
    3. or $13, $6, $2
    4. add $14, $2, $2
    5. sw $15, 100($2)
  • Step-by-step 解答
    1. sub 把結果寫入 $2
    2. and 依賴 $2。在 and 進入 EX 時,sub 剛進 MEM。這是 EX Hazard。解答:由 EX/MEM forwarding 到 ALU 輸入。
    3. or 依賴 $2。在 or 進入 EX 時,sub 剛進 WB。這是 MEM Hazard。解答:由 MEM/WB forwarding 到 ALU 輸入。
    4. add 依賴 $2sub 此時已經寫回,加上暫存器「前半週期寫入、後半週期讀出」的硬體特性,No Hazard,直接讀取即可。
    5. sw 也是正常讀取,No Hazard
  • 常考頻率:★★★★★
  • 重要程度:★★★★★ (佔分極重,請務必熟練)

[題型 4: Load-Use Hazard 判斷]

  • 題目lw $2, 20($1) 緊接 and $4, $2, $5
  • Step-by-step 解答
    1. lw 在 EX 階段 (ID/EX.MemRead=1) 時,發現目標暫存器 $2 和下一道指令 (and) 在 ID 階段的需求衝突。
    2. 觸發 Hazard Detection Unit:凍結 PC 與 IF/ID,並把 EX 控制訊號設為 0 (產生 Bubble)。
    3. 延遲一週期後,lw 抵達 WB,再透過 Forwarding 將讀到的資料送給 and 的 EX 階段。
  • 變化考法:考題若將 lwand 中間安插一個無關指令,Stall 就不會發生,因為距離被拉開了!

4. 控制危險與分支預測 (Control Hazards & Branch Prediction)#

觀念與公式#

  • 直觀意義:遇到 beq 分支指令,不知道要不要跳,但後面的指令已經排隊進來了。
  • 解法 1:Flush (Flush on Branch):預設不跳 (Predict-not-taken)。如果事後發現要跳,就把剛抓進來的錯誤指令清除 (IF.Flush 變 NOP)。
  • 解法 2:提前判斷 (Moving Branch Execution Earlier):把 Branch Address 運算跟 Register 比對 (XOR) 從 EX 提早到 ID 階段。這樣猜錯的懲罰 (Penalty) 就能從 3 cycles 降到 1 cycle。
  • 進階預測:Dynamic Branch Prediction:使用 Branch History Table (BHT) 記錄過去跳或不跳,猜錯才 Flush 並翻轉預測位元。
  • 編譯器優化:Delayed Branch:把「無論如何都該執行的指令」搬到 Branch 後面的 Delay Slot,這樣就完全 0 Penalty (MIPS 早期經典做法)。

實戰演練(題型大全)#

[題型 5: Branch Penalty 計算]

  • 題目:若分支判斷放在 MEM 階段,預測不跳卻跳了,會產生多少 Penalty?若提早到 ID 階段呢?
  • Step-by-step 解答
    1. 若在 MEM 階段才決定 (第 4 階段):代表 IF, ID, EX 抓進來的 3 個指令全部作廢,Penalty = 3 cycles。
    2. 若在 ID 階段決定 (第 2 階段):IF 階段抓進來的 1 個指令作廢,Penalty = 1 cycle。
  • 常考頻率:★★★★☆
  • 重要程度:★★★★☆ (重點在評估「提早判斷硬體成本」與「效能提升」的 trade-off)

5. 例外與指令級平行化 (Exceptions & ILP)#

觀念與公式#

  • Exceptions (例外):來自 CPU 內部 (如 Overflow, Undefined Opcode)。
  • Interrupts (中斷):來自外部 I/O。
  • 處理機制:停止執行,紀錄問題指令位址於 EPC (Exception Program Counter),紀錄原因於 Cause Register,把出問題指令之後的指令全數 Flush,跳轉至 OS Handler 8000 00180
  • ILP (Instruction-Level Parallelism):超純量架構 (Superscalar)。
    • Static Multiple Issue:編譯器將指令兩兩打包 (例如:一個 ALU + 一個 Load/Store) 送入管線。
    • Loop Unrolling (迴圈展開):複製迴圈主體,並使用 Register Renaming (換不同暫存器名字) 來消除假性資料相依 (Name Dependence/Anti-dependence)。

實戰演練(題型大全)#

[題型 6: Loop Unrolling & Scheduling]

  • 題目:針對 Dual-issue MIPS 進行迴圈排程,消除 Load-Use Hazard,並計算展開後的 IPC。
  • Step-by-step 解答
    1. 原始迴圈有 lwaddu 的 Load-use hazard 導致 Stall。
    2. 展開迴圈 4 次,將 4 個獨立的 lw 集中排在最前面,接著排 4 個 addu,最後排 4 個 sw
    3. 利用編譯器重新配置位移量 (Offset: 0, 4, 8, 12)。
    4. 計算執行時間:8 個 cycles 完成 14 個指令。IPC = 14/8=1.7514 / 8 = 1.75 (逼近峰值 2.0)。
  • 常考頻率:★★★☆☆
  • 重要程度:★★★★☆ (這是鑑別度極高、用來拉開分數差距的進階題型)

6. 補充#

  • 盲點 1:算總執行時間忘記減一。計算連續 NN 個指令的執行時間,公式是 (Stages+N1)(Stages + N - 1)!如果有 Stall,直接在後面加上 Stall cycles 的數量即可。
  • 盲點 2:Load-use Stall 忽略凍結。看到 lw 寫入某暫存器,下一行馬上要用,請毫不猶豫加入 1 cycle stall (Bubble)。很多學生以為 Forwarding 萬能,但在 Load-use 時 Forwarding 必須伴隨 Stall 才來得及。
  • 盲點 3:暫存器前半寫後半讀的硬體神技。如果是「隔了一行」的指令 (例如:第一行寫入 $1,第四行要讀取 $1),此時不需要 Forwarding!因為 Register File 具有「前半週期寫入、後半週期讀取」的特性,直接讀就是最新的資料。
  • 盲點 4:Double Data Hazard (連環車禍)。當連續三個指令操作同一個暫存器 (如 add $1 -> add $1 -> add $1),EX Hazard 和 MEM Hazard 條件會同時成立。此時 Forwarding 必須優先取最新 (EX Hazard) 的值!撰寫控制邏輯時,MEM Hazard 條件必須加上 (EX/MEM.RegRd != ID/EX.RegRs) 確保不被較舊的值覆蓋。這是手寫題超級常錯的死穴!
  • 盲點 5:Branch 提早到 ID 的隱藏代價。把 Branch 提早到 ID 階段判斷,會導致「需要的資料必須提早準備好」。如果剛好前一道指令是 ALU 運算且會影響 Branch 條件,原本在 EX 判斷來得及 Forwarding 的,現在可能被迫必須塞 Stall 才能在 ID 階段進行 XOR 比較。審題時務必看清楚「Branch 在哪一階段執行」。

第六章:記憶體階層架構深度解析(Memory Hierarchy)#

1. 快取缺失大歸類與寫入策略 (3C Miss Model & Write Strategy)#

觀念與公式#

(1) 快取缺失三元模型 (3C Miss Model)#

快取缺失(Cache Miss)依其底層硬體成因,可精準分類為以下三種模型(常考於觀念情境辨析):

  • 強制性缺失 (Compulsory Miss / Cold-start Miss):當程式剛啟動或首次存取某個記憶體區塊時,該資料從未進入過快取,因而必然發生的第一次缺失。
  • 容量性缺失 (Capacity Miss):當程式在某段時間內頻繁存取的工作集(Working Set)體積,大於快取的總容量時。即使快取採用完全相聯(Fully-Associative)完美擺放,資料仍會因空間不足被輪流踢出而導致缺失。
  • 衝突性缺失 (Conflict Miss / Collision Miss):專門發生在直接映射(Direct-Mapped)或組相聯(Set-Associative)快取中。當多個不同的記憶體位址因餘數映射公式,同時爭奪同一個快取組(Set),導致彼此瘋狂交替踢走對方,此時快取的其餘空間可能多數仍是空的。
(2) 寫入策略與缺失分配 (Write Strategy)#

當 CPU 執行寫入指令(如 sw)時,硬體必須權衡速度與資料一致性:

  • 寫透策略 (Write-Through):不論快取是否命中,資料同時且立刻寫入快取與主記憶體。缺點是每次寫入都要同步忍受慢速的 DRAM 延遲。

  • 黃金搭檔寫繞過 (No-Write Allocate)。當寫入缺失時,直接繞過快取去修改主記憶體,不把區塊搬上快取,省下頻寬。

  • 寫回策略 (Write-Back):寫入命中時,只將新資料更新到快取中,並將該列快取線(Cache Line)標記為 Dirty bit = 1(髒污位元)不立刻修改主記憶體。只有當這列資料未來被 LRU 演算法選中、準備被踢出(Evict)時,硬體才會檢查 Dirty bit 並將其整條寫回主記憶體。

  • 黃金搭檔寫分配 (Write Allocate)。當寫入缺失時,大費周章將該 Block 從主記憶體載入到快取,隨後再執行快取寫入。核心理念是利用時間局部性,打賭未來對該區塊的無數次讀寫都能在快取中以 1 cycle 爆發命中。

(3) 架構師的硬體權衡參數 (Cache Trade-offs)#
  • 固定總容量,放大區塊大小 (Block Size \uparrow)
  • 強大的空間局部性使 Compulsory Miss 下降
  • 但根據公式: 總格數 (Blocks)=Cache 總容量Block Size\text{總格數 (Blocks)} = \frac{\text{Cache 總容量}}{\text{Block Size}}

當總容量固定,Block Size 放大,快取內部的總格數(或總組數)反而會大幅縮水。這會造成嚴重的「沙發效能陷阱」,導致 Conflict Miss 劇烈上升

  • 固定總容量與區塊,提升相聯度 (Associativity \uparrow)
  • 擺放極度靈活,使得 Conflict Miss 顯著下降
  • Capacity Miss 完全沒有影響(容量缺失只與 Cache 總容量大小有關)。
  • 致命硬體代價:由於多個 Way 需要平行比對,硬體內部需要成倍增加比較器(Comparator),導致晶片面積增大、功耗與成本爆炸。同時,後面串接的大型多路複用器(MUX)會拉長電路延遲,造成 Hit Time(命中時間)變長

實戰演練#

題目一:3C Miss Model 情境微觀辨析(精準歸類)#

假設有一個 32 位元系統,內建一個容量為 64 KB64\text{ KB}、Block Size 為 64 Bytes64\text{ Bytes} 的 2-way Set-Associative Cache。請判斷下列三種獨立發生的記憶體存取缺失,分別屬於 3C Miss 中的哪一種,並簡述其原因:

  • (1) 電腦剛開機,CPU 執行第一行核心指令時發生的 Cache Miss。
  • (2) 程式要處理一個大小為 2 MB2\text{ MB} 的大型影像矩陣,由於陣列連續存取所需的空間遠大於 64 KB64\text{ KB},導致在迴圈後段存取時,先前載入的資料早已被全部剔除而發生的 Miss(假設此時排除排擠問題)。
  • (3) 某段迴圈在極短時間內,交替讀取主記憶體實體位址 0x000010000x00011000。經硬體計算發現,這兩個位址因為 Modulo 公式,剛好都會被映射到 Set 64。因為它們瘋狂交替踢走對方,導致這個迴圈每次存取都發生 Miss,但此時整個 Cache 其實還有超過 90% 的空間是空的。

【Step-by-step 詳細解析】

  • (1) 答案:Compulsory Miss

  • 解析:電腦剛開機執行第一行指令,該記憶體位址是生涯第一次被讀取,快取內為空(Valid bit = 0),此為典型的冷啟動缺失。

  • (2) 答案:Capacity Miss

  • 解析:工作集資料體積(2 MB2\text{ MB})遠遠碾壓了快取的總容納極限(64 KB64\text{ KB}),即使快取設計得再完美也放不下,因容量耗盡被輪替踢出,故歸類為容量缺失。

  • (3) 答案:Conflict Miss

  • 解析:關鍵特徵在於「整個 Cache 還有 90% 的空間是空的」。這代表缺失絕非因為總容量不夠(非 Capacity),而是因為 0x000010000x00011000 這兩個特定的高頻存取位址,倒楣地映射到了同一個格子(Set 64),在局部發生了嚴重的排擠衝突。


題目二:Write Strategy 硬體運作流程#

現有一台處理器,其 L1 Data Cache 採用 Write-Back(寫回策略) 搭配 Write Allocate(寫分配),且替換演算法採用 LRU

  • (1) 當 CPU 執行一個 sw(寫入資料)指令且 Cache Hit 時,硬體內部會做出什麼動作?此時會立刻去修改 Main Memory 的資料嗎?
  • (2) 承上題,如果此時不幸發生了 Read Miss(讀取缺失),且經 LRU 算過後,被選中要被踢出(Evict)的那一列 Cache Line 的 **Dirty bit 為 1**。請詳細寫出硬體此時必須依序執行的底層運存步驟。
  • (3) 為什麼在業界設計中,Write-Through 通常固定搭配 No-Write Allocate,而 Write-Back 則固定搭配 Write Allocate?請從效能工程的角度解釋原因。

【Step-by-step 詳細解析】

  • (1) 答案:

  • 硬體動作:硬體會直接將新資料寫入到 L1 Data Cache 對應的欄位中,並**將該快取列的 Dirty bit 標記為 1**

  • 是否修改 Main Memory絕對不會。這正是 Write-Back 的精髓,將慢速的記憶體寫入動作延遲到區塊被淘汰之時,以此節省寶貴的 CPU 時間。

  • (2) 答案(標準硬體狀態鏈流動順序):

  1. 寫回髒污區塊 (Write Back):快取控制器偵測到被 LRU 挑出的 Victim(犧牲者)區塊之 Dirty bit 為 1,代表其內容已被修改、與記憶體不一致。硬體會率先將此整條 Cache Block 寫回主記憶體(DRAM)對應的實體位址。
  2. 載入全新區塊 (Fetch):當髒污區塊清空後,快取控制器向主記憶體發出讀取請求,將 CPU 當前真正需要讀取的全新實體區塊完整搬運(Fetch)上來,填入該清空的位置。
  3. 重設狀態標籤:將這一格的 **Dirty bit 清除為 0**(因為剛從記憶體搬上來,兩邊資料完全一致),並將 **Valid bit 設為 1**
  4. 交付資料:最後把目標資料透過內部匯流排完美交付給 CPU,完成本次讀取任務。
  • (3) 答案:
  • Write-Through + No-Write Allocate:因為 Write-Through 無論如何都必須同步將資料寫進主記憶體。既然在快取沒命中,最省時的做法就是直接寫去主記憶體(DRAM)即可,不需要大費周章再把整條區塊搬上快取,這能有效保護快取空間不被污染,並節省匯流排頻寬。
  • Write-Back + Write Allocate:Write-Back 的核心目的是讓未來的讀寫都在超高速的快取中爆發命中。雖然這次 Miss 必須多花時間從主記憶體分配並載入區塊,但只要成功搬上來,接下來對這個區塊的連續無數次寫入就通通只要 1 cycle 就能在快取搞定。高回報率完全值得初次的搬運代價。

2. 多階快取架構與記憶體頻寬優化 (Multilevel Caches & Memory Optimization)#

觀念與公式#

(1) 多階快取的階層式權衡 (Architect’s Goals)#

為了解決「處理器-記憶體效能鴻溝(Processor-Memory Performance Gap)」,現代架構設計了多層防線:

  • L1 Cache(第一線戰場)

  • 核心目標極致的快(Minimize Hit Time)

  • 設計特徵:緊貼 CPU 核心,容量極小(16 KB64 KB16\text{ KB} \sim 64\text{ KB}),相聯度極低(通常 2-way 或 Direct-Mapped),確保在 1 個 cycle 內做出回應。

  • L2/L3 Cache(第二/三道防線)

  • 核心目標極低的缺失率(Minimize Miss Rate),死命攔截住任何企圖外流到主記憶體的存取。

  • 設計特徵:容量巨大(256 KB8 MB+256\text{ KB} \sim 8\text{ MB}+),相聯度極高(8-way \sim 32-way),雖然 Hit Time 稍慢(10~30 cycles),但比起去 Main Memory 等幾百個 cycles,依然是天壤之別。

(2) 雙層快取 AMAT 終極結算公式#

當引入 L2 快取後,平均記憶體存取時間(AMAT)展開為三層聯動公式:

AMAT=Hit TimeL1+Miss RateL1×Miss PenaltyL1\text{AMAT} = \text{Hit Time}_{L1} + \text{Miss Rate}_{L1} \times \text{Miss Penalty}_{L1}

而 L1 的 Miss Penalty,實質上就是去 L2 尋找資料的平均時間:

Miss PenaltyL1=Hit TimeL2+Local Miss RateL2×Miss PenaltyL2\text{Miss Penalty}_{L1} = \text{Hit Time}_{L2} + \text{Local Miss Rate}_{L2} \times \text{Miss Penalty}_{L2}

  • 【🚨 缺失率名詞大陷阱】
  1. Local Miss Rate(局部缺失率)Local Miss RateL2=L2 Miss 總數進入 L2 的存取總數 (即 L1 Miss 數)\text{Local Miss Rate}_{L2} = \frac{\text{L2 Miss 總數}}{\text{進入 L2 的存取總數 (即 L1 Miss 數)}}

一般計組題目若無特別說明,「L2 快取缺失率」預設皆為此項。 2. Global Miss Rate(全域缺失率)Global Miss RateL2=L2 Miss 總數CPU 發出的總存取數=Miss RateL1×Local Miss RateL2\text{Global Miss Rate}_{L2} = \frac{\text{L2 Miss 總數}}{\text{CPU 發出的總存取數}} = \text{Miss Rate}_{L1} \times \text{Local Miss Rate}_{L2}

(3) 主記憶體(DRAM)頻寬優化策略#

當快取全數失守、必須去 DRAM 搬運一整條 Block(假設大小為 NN 個 Words)時,有三種硬體組織架構:

  • 單字寬度組織 (One-word-wide):記憶體與匯流排寬度皆為 1 Word1\text{ Word}。每次搬運都必須獨立重複執行「送位址 + DRAM啟動 + 傳輸 1 Word」的完整流程,速度最慢。

  • 加寬組織 (Wide Memory):直接加寬記憶體與匯流排。路多寬,資料就能併排跑多大。可以一次送出位址、一次讀取並同時打包傳輸一整條 Block

  • Total Miss Penalty=傳送位址時間+DRAM 存取時間+1 次打包傳輸時間\text{Total Miss Penalty} = \text{傳送位址時間} + \text{DRAM 存取時間} + \text{1 次打包傳輸時間}

  • 交錯式儲存組織 (Interleaved Memory)【期末考最愛考!】 內部拆成多個獨立的 Memory Banks。可以平行(同時)啟動多個 Bank 讀取,等一次 DRAM 時間,所有資料就在門口準備好了。但為了省錢,與主機連接的資料匯流排寬度維持窄小的 1 Word1\text{ Word},因此傳輸時必須排成一縱隊依序過馬路。

  • Total Miss Penalty=傳送位址時間+DRAM 存取時間+(N×單字傳輸時間)\text{Total Miss Penalty} = \text{傳送位址時間} + \text{DRAM 存取時間} + (N \times \text{單字傳輸時間})

實戰演練#

題目一:雙層快取(L1/L2)AMAT 與 CPI 聯動地獄計算題#

現有一台高時脈處理器,運作時脈為 2.5 GHz2.5\text{ GHz}(意即 1 cycle=0.4 ns1\text{ cycle} = 0.4\text{ ns}),在理想快取狀態下的 Base CPI=2.0\text{Base CPI} = 2.0。所有指令中,有 40%40\% 的指令是資料存取指令(LoadStore)。系統配備了兩級快取,參數如下:

  • L1 I-Cache:Miss Rate=2%\text{Miss Rate} = 2\%Hit Time=1 cycle\text{Hit Time} = 1\text{ cycle}
  • L1 D-Cache:Miss Rate=5%\text{Miss Rate} = 5\%Hit Time=1 cycle\text{Hit Time} = 1\text{ cycle}
  • L2 Unified Cache:Local Miss Rate=20%\text{Local Miss Rate} = 20\%Hit Time=8 cycles\text{Hit Time} = 8\text{ cycles}
  • 主記憶體(Main Memory):存取一次需要固定的時間 60 ns60\text{ ns}

請詳細解答下列問題:

  • (1) 請問主記憶體存取一次,對這台 CPU 而言是多少個 Penalty Cycles?
  • (2) 請問 L2 D-Cache 的 Global Miss Rate(全域缺失率)是多少?
  • (3) 當 L1 Data Cache 發生 Miss 時,平均需要花多少個 Cycles(L1 Miss Penalty)才能從下層系統(L2 + Memory)取回資料?
  • (4) 這台處理器在執行該程式時,最終實際的總 CPI 是多少?

【Step-by-step 詳細解析】

  • (1) 解答:150 cycles

  • 計算Memory Penalty Cycles=記憶體固定延遲CPU 週期時間=60 ns0.4 ns=150 cycles\text{Memory Penalty Cycles} = \frac{\text{記憶體固定延遲}}{\text{CPU 週期時間}} = \frac{60\text{ ns}}{0.4\text{ ns}} = 150\text{ cycles}

  • (2) 解答:1% (或 0.01)

  • 計算Global Miss RateL2=L1 D-Cache Miss Rate×L2 Local Miss Rate=5%×20%=0.01=1%\text{Global Miss Rate}_{L2} = \text{L1 D-Cache Miss Rate} \times \text{L2 Local Miss Rate} = 5\% \times 20\% = 0.01 = 1\%

  • (3) 解答:38 cycles

  • 計算:帶入雙層 Penalty 公式。當 L1 缺失時,一定要先花 8 cycles8\text{ cycles} 檢查 L2。如果 L2 沒中(機率 20%20\%),才需要外流去 Main Memory 等 150 cycles150\text{ cycles}

L1 Data Miss Penalty=Hit TimeL2+Local Miss RateL2×Mem Penalty=8+0.20×150=8+30=38 cycles\text{L1 Data Miss Penalty} = \text{Hit Time}_{L2} + \text{Local Miss Rate}_{L2} \times \text{Mem Penalty} = 8 + 0.20 \times 150 = 8 + 30 = 38\text{ cycles}

  • (4) 解答:3.52
  • 計算:由於 L2 是統一快取(Unified),不論是指令(I)還是資料(D)只要漏出 L1,去 L2 + Memory 撈資料的懲罰都是相同的 38 cycles38\text{ cycles}
  • 計算 Instruction Stall: I-Stall=1×2% (I-Cache Miss Rate)×38=0.76 cycles\text{I-Stall} = 1 \times 2\% \text{ (I-Cache Miss Rate)} \times 38 = 0.76\text{ cycles}

(每條指令都有 1 次抓取指令的動作)

  • 計算 Data Stall: D-Stall=40% (Data 指令佔比)×5% (D-Cache Miss Rate)×38=0.76 cycles\text{D-Stall} = 40\% \text{ (Data 指令佔比)} \times 5\% \text{ (D-Cache Miss Rate)} \times 38 = 0.76\text{ cycles}

  • 結算實際總 CPI: Total CPI=Base CPI+I-Stall+D-Stall=2.0+0.76+0.76=3.52\text{Total CPI} = \text{Base CPI} + \text{I-Stall} + \text{D-Stall} = 2.0 + 0.76 + 0.76 = 3.52


題目二:主記憶體組織(Memory Organizations)與週期計算大題#

假設目前系統要從 DRAM 搬回一個大小為 4 個 Words 的 Cache Block。已知主記憶體與匯流排的硬體延遲參數如下:

  • 傳送位址時間:固定花費 1 cycle1\text{ cycle}
  • DRAM 存取時間(Latency):每啟動一次讀取,DRAM 內部晶片需要花費 30 cycles30\text{ cycles} 才能把資料準備好。
  • 資料傳輸時間:匯流排每傳送 1 Word1\text{ Word} 的資料,需要花費 2 cycles2\text{ cycles}

請分別計算在以下三種不同的主記憶體組織架構下,CPU 發生一次 Miss 所需付出的總缺失懲罰(Total Miss Penalty,單位為 cycles):

  • 架構 (A):單字寬度儲存組織(One-word-wide Memory Organization)
  • 架構 (B):加寬儲存組織(Wide Memory Organization,寬度加寬為 4 Words)
  • 架構 (C):四路交錯式儲存組織(4-bank Interleaved Memory Organization,匯流排維持 1 Word 寬)

【Step-by-step 詳細解析】

  • 架構 (A) 解答:132 cycles

  • 解析:因為每次只能定址傳輸 1 個 Word,整套動作必須重複 4 次。

  • 單次循環=1 (傳位址)+30 (DRAM存取)+2 (傳輸)=33 cycles\text{單次循環} = 1\text{ (傳位址)} + 30\text{ (DRAM存取)} + 2\text{ (傳輸)} = 33\text{ cycles}

  • 總時間=33×4 (個Words)=132 cycles\text{總時間} = 33 \times 4\text{ (個Words)} = 132\text{ cycles}

  • 架構 (B) 解答:33 cycles

  • 解析:路加寬了 4 倍,記憶體一次吐出 4 個 Words,超寬的匯流排還能把這 4 個 Words 綁成一大捆,在「1 次傳輸時間內(即 2 cycles)」一口氣通通運回 CPU。

  • 總時間=1 (傳位址)+30 (DRAM存取)+2 (超寬頻一次傳完)=33 cycles\text{總時間} = 1\text{ (傳位址)} + 30\text{ (DRAM存取)} + 2\text{ (超寬頻一次傳完)} = 33\text{ cycles}

  • 架構 (C) 解答:39 cycles

  • 解析:記憶體內部拆成 4 個 Banks,所以可以同時平行啟動 DRAM 存取,我們只需要等 1 次 30 cycles30\text{ cycles},4 個 Words 就都在各自的 Bank 門口準備好了。但由於匯流排寬度維持窄小的 1 Word,這 4 個 Words 沒辦法並排跑,必須排成一縱隊,一個接一個傳過馬路(傳輸時間需累加)。

  • 總時間=1 (傳位址)+30 (4個Bank平行存取)+[4 (個Words)×2 (傳輸)]=1+30+8=39 cycles\text{總時間} = 1\text{ (傳位址)} + 30\text{ (4個Bank平行存取)} + [4\text{ (個Words)} \times 2\text{ (傳輸)}] = 1 + 30 + 8 = 39\text{ cycles}


3. 虛擬記憶體與分頁機制 (Virtual Memory & Paging)#

觀念與公式#

(1) 虛擬記憶體的終極定位 (The Illusion)#

虛擬記憶體是硬體與作業系統(OS)聯手打造的宏大魔術。它為每個獨立的進程(Process)提供了一個「私有、連續、從零開始」的虛擬位址空間(Virtual Address Space)。此時,主記憶體(DRAM)本質上變成了次級儲存裝置(硬碟/SSD)的「快取(Cache)」

(2) 快取 vs 虛擬記憶體之名詞對照表#

為了讓觀念無縫平移,架構師將名詞做了一對一的對照:

快取架構 (Cache)虛擬記憶體架構 (Virtual Memory)
Cache Block (快取區塊)Page (分頁)
Cache Frame (快取格)Page Frame (實體分頁框)
Cache Miss (快取缺失)Page Fault (分頁錯誤)
(3) 由「恐怖懲罰」逼出的四項架構設計抉擇#

一旦發生 Page Fault,CPU 必須去慢速的硬碟(Disk/SSD)搬資料,這會付出高達數百萬個時脈週期的極致懲罰。為了死命降低 Page Fault 的機率,虛擬記憶體做出了與 Cache 截然不同的設計:

  1. 分頁體積做得很巨(Page Size 大):通常是 4KB 甚至更大。透過極強的空間局部性,攤提每次啟動硬碟讀取的高昂時間。
  2. 採用全關聯式擺放 (Fully Associative):任何虛擬分頁都可以自由存放到實體記憶體的任何角落,這樣能使用最靈活的演算法(如 LRU)把 Page Fault 的機率壓到最低。
  3. 遺失由軟體(OS Handler)全權處理:既然 Page Fault 要等數百萬 cycles,硬體花十幾個 cycle 呼叫 OS 軟體根本無傷大雅。OS 會在此時進行進程上下文切換(Context Switch),把 CPU 讓給別的程式使用,免得處理器原地白白發呆。
  4. 強制使用寫回策略 (Write-Back):每次寫入都要同步改硬碟(Write-Through)會直接卡死系統。硬體只有當分頁要被踢出實體記憶體時,才檢查 Dirty bit 寫回硬碟。
(4) 位址翻譯與分頁表 (Address Translation)#

為了解決 Fully Associative 找不到資料的定位問題,OS 在 DRAM 中建立了一個索引地圖,稱為分頁表(Page Table)。 CPU 發出的虛擬位址(Virtual Address, VA)會被拆成兩部分:

  • Virtual Page Number (VPN,虛擬分頁編號):作為 Page Table 的陣列索引(Index)。
  • Page Offset (分頁偏移量):代表資料在該分頁內的確切位置(不參與翻譯,直接照抄)。

透過 VPN 索引查表後,若該條目(Page Table Entry, PTE)的 Valid bit 為 1,代表分頁待在實體記憶體中,此時會吐出 Physical Page Number (PPN,實體分頁編號),並與 Page Offset 拼接成實體位址(Physical Address, PA);若 Valid bit 為 0,則代表觸發 Page Fault

(5) 分頁表拆分核心公式#

Page Offset 位元數=log2(Page Size 單位為 Bytes)\text{Page Offset 位元數} = \log_2(\text{Page Size 單位為 Bytes})

VPN 位元數=虛擬位址總位元數 (VA)Page Offset 位元數\text{VPN 位元數} = \text{虛擬位址總位元數 (VA)} - \text{Page Offset 位元數}

分頁表總條目數 (PTEs)=2VPN 位元數\text{分頁表總條目數 (PTEs)} = 2^{\text{VPN 位元數}}

實戰演練#

題目一:虛擬記憶體軟硬體處理機制辨析#

為什麼處理 Cache Miss 需要「純硬體線路(Hardware)」控制,而處理 Page Fault 卻可以容忍跳躍到作業系統的「軟體(Software OS Handler)」來處理?

【Step-by-step 詳細解析】

  • Cache Miss 的情境:快取缺失的懲罰非常低(通常僅有幾十個 cycles),如果此時跳入作業系統執行軟體中斷處理,光是保護暫存器現場(Context Overhead)就要花費數百個 cycles,完全是因小失大。因此,Cache Miss 必須用純硬體線路以極速完成
  • Page Fault 的情境:分頁錯誤去磁碟讀取資料的懲罰高達數百萬個 cycles。與這段漫長的等待時間相比,OS 軟體中斷處理所帶來的幾百個 cycle 開銷根本微不足道。容忍跳入軟體,能讓 OS 有機會執行 Context Switch 切換到其他進程工作,大幅拉高 CPU 的整體整體吞吐量(Throughput)

題目二:分頁位址拆分與大小結算#

假設某電腦系統採用虛擬記憶體架構,虛擬位址(VA)為 32 位元,實體位址(PA)為 30 位元,每個 Page 的大小為 8KB。請精準計算出:

  • (a) Page Offset 需要多少位元(bits)?
  • (b) Virtual Page Number (VPN) 有多少位元?
  • (c) Page Table 中總共包含多少個 Page Table Entries (PTEs)?

【Step-by-step 詳細解析】

  • (a) 解答:13 bits
  • 計算:先將 Page Size 換算為 2 的次方: 8 KB=8×1024 Bytes=8192 Bytes=213 Bytes8\text{ KB} = 8 \times 1024\text{ Bytes} = 8192\text{ Bytes} = 2^{13}\text{ Bytes}

因此,需要 13 bits13\text{ bits} 的 Page Offset 來對分頁內的每個 Byte 進行定址。

  • (b) 解答:19 bits
  • 計算:虛擬位址由 VPN 與 Page Offset 組成:

VPN Bits=VA BitsPage Offset Bits=3213=19 bits\text{VPN Bits} = \text{VA Bits} - \text{Page Offset Bits} = 32 - 13 = 19\text{ bits}

  • (c) 解答:2192^{19} 個 (或 524,288 個)
  • 計算:分頁表必須涵蓋所有的虛擬分頁編號可能性:

PTE 總數=2VPN Bits=219 個條目\text{PTE 總數} = 2^{\text{VPN Bits}} = 2^{19}\text{ 個條目}


4. TLB 翻譯旁路緩衝器與快取終極大融合 (TLB & Cache Integration)#

觀念與公式#

(1) 救速神器:TLB (Translation Lookaside Buffer)#

由於 Page Table 存放在慢速的 DRAM 中,導致 CPU 每次想拿一個資料,都必須先去 DRAM 讀一次 Page Table 翻譯,再讀一次實體位址,存取時間直接變為兩倍。 為了消除這個致命缺點,架構師在 CPU 內部的 MMU(記憶體管理單元)中建立了一個專門用來快取「分頁表條目(PTE)」的超高速小快取,稱為 TLB。CPU 翻譯位址時會先問 TLB,若 TLB Hit,只需 0.5 \sim 1 cycle 就能瞬間拿到實體位址(PA)。

(2) 四合一系統聯動狀態之「可能與不可能」矩陣#

TLB、Page Table、Cache、DRAM 全數交織在一起時,期末考最常考的便是判斷某種硬體組合是否存在矛盾:

組合狀態是否可能發生?硬體底層真相原理解析
TLB Miss + Page Hit + Cache Miss可能 (Possible)最經典的冷啟動或跨大步記憶體存取。資料確實待在 DRAM 中(Page Hit),只是其翻譯地圖剛剛好不在 TLB 內(TLB Miss),且資料也尚未被搬移上快取(Cache Miss)。
TLB Miss + Page Hit + Cache Hit可能 (Possible)翻譯地圖在 TLB 中剛好被擠掉(TLB Miss),但實體資料早已透過別的別名或前一次存取安穩地躺在 Cache 中(Cache Hit)。
TLB Hit + Page Fault絕對不可能世紀矛盾! TLB 能夠命中(TLB Hit)的前提,是裡面裝有合法且 Valid = 1 的實體位址。既然翻譯地圖有效,代表資料百分之百安穩地躺在實體記憶體中,絕對不可能觸發 Page Fault(去硬碟找資料)。
Cache Hit + Page Fault絕對不可能世紀矛盾! Cache 裡面裝的只不過是實體記憶體的「局部拷貝」。如果都發生了 Page Fault(代表實體記憶體中根本沒有這個分頁),Cache 裡面絕對不可能憑空變出這筆資料。

實戰演練#

題目一:終極四合一聯動追蹤大題#

假設某系統同時配備了 TLBPage TableCache。現在 CPU 發出了一個記憶體讀取請求,但很不幸地,這個請求在硬體中依序發生了:TLB Miss \rightarrow Page Table Hit \rightarrow Cache Miss。請詳細寫出底層硬體與系統接下來必須依序執行的「4 個核心步驟」。

【Step-by-step 詳細解析(標準晶片規範書規範寫法)】

  • Step 1:去 DRAM 走訪分頁表(修補地圖)

  • 由於 TLB Miss,MMU 無法在第一時間完成翻譯。硬體被迫手持虛擬分頁編號(VPN)為索引,走訪位於 DRAM 中的 Page Table。因為 Page Table Hit(Valid bit = 1),硬體順利讀出對應的實體分頁編號(PPN)。

  • Step 2:組裝並更新地圖(更新 TLB)

  • MMU 將讀出的 PPN 與原本的 Page Offset 完美拼接,產生最終的實體位址(PA)。同時,為了確保下一次存取不用再跑去遙遠的 DRAM 查表,硬體會將這筆新翻譯好的對應關係立刻寫入(更新)TLB

  • Step 3:持實體位址查 Cache(搬移 Block)

  • 硬體拿著剛出爐的實體位址(PA)去查 Cache。然而不幸發生 Cache Miss。此時快取控制器被迫再次啟動主記憶體(DRAM),將包含該目標資料的一整個實體區塊(Cache Block)從 DRAM 搬運(Fetch)上來,載入並更新到 Cache 中

  • Step 4:快取命中,交付 CPU(完美收工)

  • 當資料成功入駐 Cache 後,CPU 再次存取該位址時便會觸發 Cache Hit,快取立刻將 CPU 真正想要的那個 Word 資料透過內部匯流排交付給暫存器,順利恢復指令的執行!


5.補充#

  1. 「固定總容量下 Block 放大」的 Conflict 飆升陷阱
  • 學生的直覺錯誤:Block 變大,格數變多,所以 Conflict 變少?
  • 考前救命真相完全顛倒! 當總容量固定,你把每個 Block 的體積放大,Cache 內部能放的總格數反而會急劇縮水(例如大沙發擠掉小課桌)。格子變少,不同的記憶體位址映射到同一個格子的爭奪戰就會變得極度殘烈,因為搬資料一次就要搬一整個block,Conflict Miss 會不降反升
  1. AMAT 公式帶入時的 Local vs Global 混淆點
  • 學生的直覺錯誤:在計算 AMAT=HTL1+MRL1×(HTL2+MRL2×Memory Penalty)\text{AMAT} = \text{HT}_{L1} + \text{MR}_{L1} \times (\text{HT}_{L2} + \text{MR}_{L2} \times \text{Memory Penalty}) 時,直接將題目給的 L2 缺失率帶入最內層的 MRL2\text{MR}_{L2}
  • 考前救命真相:公式最內層與 Memory Penalty\text{Memory Penalty} 相乘的,必須是 Local Miss Rate(代表漏出 L1 的那群人中,有多少比例又漏出了 L2)。如果題目陰險地給了你 Global Miss Rate,你必須先透過公式 Global MR=MRL1×Local MRL2\text{Global MR} = \text{MR}_{L1} \times \text{Local MR}_{L2} 進行反推換算,才能帶入 AMAT 公式!
  1. DRAM 頻寬優化計算中的「馬路寬度與排隊」地獄
  • 學生的直覺錯誤:分不清 Wide Memory 與 Interleaved Memory 的時間公式,通通加在一起。
  • 考前救命真相
  • Wide Memory:馬路超寬。DRAM 存取完 4 個 Words 後,4 個 Words 可以並排在 1 次傳輸時間內一口氣通通傳完(傳輸時間算 1 次)。
  • Interleaved Memory:馬路很窄(匯流排維持 1 Word 寬)。多個 Bank 雖然能平行同時啟動存取(存取延遲只算 1 次),但吐出 4 個 Words 後馬路太窄無法並排,這 4 個 Words 必須乖乖排成一縱隊,一隻隻依序傳過馬路(傳輸時間必須乘以 44 倍)。
  1. TLB 與 Cache 的「時空矛盾狀態」判定
  • 學生的直覺錯誤:在期末考是非填空題中,勾選「TLB Hit 且 Page Fault」為可能發生。
  • 考前救命真相這是絕對的硬體悖論! 只要記住一個黃金鐵則:「地圖在,人就一定在;人不在,拷貝就絕對不可能憑空出現。」 TLB 命中代表地圖有效 \rightarrow 分頁一定在實體記憶體中 \rightarrow 絕不可能 Page Fault。Cache 命中代表快取有拷貝 \rightarrow 實體記憶體一定早就載入了該分頁 \rightarrow 絕不可能 Page Fault。任何 Hit 與 Page Fault 組合在一起的選項,直接判定 Impossible 秒殺拿分!

文章分享

如果這篇文章對你有幫助,歡迎分享給更多人!

大二下計算機結構
https://github.com/posts/大二下計算機結構/
作者
Guo-hua
發布於
2026-07-13
許可協議
CC BY-NC-SA 4.0
Profile Image of the Author
Guo-hua
夏天還會再來...
公告
歡迎來到我的網站~
音樂
封面

音樂

暫未播放

0:00 0:00
暫無歌詞
分類
標籤
站點統計
文章
8
分類
4
標籤
23
總字數
53,865
運行時長
0
最後活動
0 天前

文章目錄