<超標量處理器概覽> 第 1 章 - 超標量處理器概覽

1.2 - 普通處理器的流水線 1.2.2 - 流水線的劃分 Pipeline CPU,其 cycle time 由最長 cycle time 的 pipeline stage 所決定 因此,最好每個 pipeline stage 的 cycle time 都是差不多長的 解決各個 pipeline stage cycle time 不平衡的方法: 合: 將多個 pipeline stages 合併成一個 stage,例如: Fetch (7 ns) & Decode (3 ns) | Operand fetch (8 ns) & Execute (5 ns) | Memory (10 ns) & Write back (3 ns) 此方法將 pipeline stages 從 5 個降為 3 個,原本各個 pipeline stage cycle time 不平衡的情況也變成:10 ns | 13 ns | 13 ns 適用於對於性能要求不高的 CPU,例如:ARM7、ARM9、Cortex-M0、Cortex-M3 因為 pipeline stage 的 cycle time 增加了,從原本的 max(7 ns, 3 ns, 8 ns, 5 ns, 10 ns, 3 ns) ⇒ 10 ns,增加為 max(10 ns, 13 ns, 13 ns) ⇒ 13 ns,cycle time 增加,就代表 CPU 的 frequency 會降低 拆: 將 pipeline stage 拆成更小的 stages,例如: Fetch (7 ns) ⇒ Fetch1 (3.5 ns) & Fetch2 (3.5 ns) 適用於高性能 CPU,因為可以提昇 CPU 的 frequency 缺點: 增加所需的硬體元件,例如:需要多個 pipeline registers 功耗會增大 較深的 pipeline 也會增加 branch misprediction 的 penalty 1.2.3 - 指令間的相依性 Instructions hazard: ...

2025/02/12 · 4 分鐘 · 658 字 · Frank Chang

<超標量處理器概覽> 第 2 章 - Cache

2.1 - Cache 的一般設計 L1 Cache 通常分為 I-Cache 和 D-Cache,為 private cache I-Cache 需要能夠在一個 cycle 內,讀取多條的指令 D-Cache 需要能在一個 cycle 內,處理多條 load/store 指令的訪問,因此需要使用 multi-port 的設計 Instruction fetch 的時候,會向 L1 Cache 嘗試讀取指令,因此 L1 Cache 也是 pipeline 的一部分 L1 Cache 必須保持跟 CPU 相近的速度,因此通常是透過 SRAM 實現的 L2 Cache 通常都是指令和資料一起 share 整個 cache,容量通常以 MB 為單位 現在大部份的 multi-core 都是 shared 同一個 L3 Cache L2 Cache 被訪問的頻率通常不是很高 (L1 Cache miss 才會訪問 L2 Cache),因此不需要使用 multi-port 的設計 需要盡可能的提昇 L2 Cache 的命中率,因為如果 L2 Cache miss,且沒 L3 Cache 的話,就需要去訪問 DRAM 了,訪問時間會很長 2.1.1 - Cache 的組成方式 Set-associative cache: ...

2025/02/13 · 11 分鐘 · 2185 字 · Frank Chang

<超標量處理器概覽> 第 3 章 - 虛擬存儲器

3.2 - 位址轉換 3.2.3 - Page Fault PTE (page table entry) 中包含: valid bit:標記這個 PTE 是否有效,當作業系統設定好 page table 後,就需要將對應 PTE 的 valid bit 設成 1 dirty bit:當一個 page 內容被更新時 (e.g. 執行 store 指令),硬體會自動將 dirty bit 設成 1,代表這個 page 如果被選中要被替換時,需要將 page 的內容 swap 回硬碟 access bit:當一個 page 被訪問 (load/store) 時,硬體會自動將 access bit 設成 1,作業系統則會定期的將 access bit 清為 0 當要替換 page table 時,就可以根據 access bit 來得知最近 page 是否有被訪問過,進而實現近似 LRU (Least Recently Used) 的替換策略 當 page 要被 swapped out 前: 要先將 D-Cache 的內容 flush 進 memory,以確保要被 swapped out 的 page 內容是最新的 將 PTE 的 valid bit 設成 0,以避免其他 CPU 或 MMU 在接下來 swap out 期間誤讀這個 page valid bit 為 0 時,代表該 page 並不存在記憶體中,當 MMU 存取時會觸發 page fault 讓作業系統從硬碟讀取 page 進記憶體 valid bit 是由作業系統在把 page 讀進記憶體後設為 1 的 執行如 RISC-V 的 sfence.vma 指令,確保 TLB 中對應的 entries 被清空,以避免 MMU 錯誤存取到被 swapped out page 的 cache 內容 3.4 - 加入 TLB 和 Cache 3.4.1 - TLB 的設計 TLB entry 中也會包含: valid bit:標記這個 TLB entry 是否有效;當 TLB entry 被 swap in 時,valid bit 會被設為 1 dirty bit:當執行 store 指令時,如果 TLB hit,就不會再訪問 PTE,也就不會更新 PTE 中的 dirty bit;只有當 TLB entry 要被替換時,才會同步至 PTE access bit:當執行 load/store 指令時,如果 TLB hit,就不會再訪問 PTE,也就不會更新 PTE 中的 access bit;只有當 TLB entry 要被替換時,才會同步至 PTE P.S. RISC-V 中,TLB entry 並沒有包含 dirty 和 access bits,作業系統需要自己確保 PTE 的更新 sfence.vma 只會將 TLB 中對應的 entries 給 invalid 而已 (針對 TLB 的部份) 如果 CPU 有支援 Svadu extension,那麼硬體就會自動更新 PTE 中的 dirty 和 access bit 如果硬體支援 access 和 dirty bits 自動更新, 作業系統只需要讀取 PTE 即可獲得最新的 access 和 dirty bits 的狀態 如果硬體不支援 access 和 dirty bits 自動更新,當 access=0 或 dirty=0 時: MMU 會觸發 page fault 作業系統在 page fault handler 中設置 access=1 或 dirty=1 作業系統得先透過設定 PTE 的 valid bit (追蹤 page 是否有被 accessed) 和 disable write permission (追蹤 page 是否有被 stored) 來當 page fault 發生時,在 page fault handler 更新 access 或 dirty bit 重新執行造成 page fault 的那道指令 也就是讓作業系統來自行管理 PTE 中 access 和 dirty bits 的內容,效能較差,但硬體設計較簡單 RISC-V privilege spec: If pte.a=0, or if the original memory access is a store and pte.d=0: If the Svade extension is implemented, stop and raise a page-fault exception corresponding to the original access type. 一般為了減少 TLB miss rate,會使用 fully-associative 來設計 TLB 缺點:TLB 容量不能太大,不然會增加查找的時間 因此,有些架構也會使用 set-associative 來設計容量比較大的 TLB 因為是 fully-associative 或 set-associative,因此 TLB entry 中,還會包含 tag 欄位 (VPN,Virtual Page Number),用來比對 TLB 是否 hit P.S. TLB entry 中的 data 是 PFN (Page Frame Number) 現代處理器架構,通常都使用 2-level TLB 1st level 採用 Harvard 架構,分為 I-TLB (指令) 和 D-TLB (數據),一般採用 fully-associative 設計 2nd level 採用 Von Neumann 架構,指令和數據共用,一般採用 set-associative 設計 現代處理器中因應程式的 size 越來越大,因此還會支持容量更大的 page E.g. 128 entries 的 TLB,只能映射到 128 * 4KB = 512 MB 大小的程式,顯然不夠用 更大的 page: 優點: 降低 TLB miss rate 缺點: 當發生 page fault 的時候,需要花更多的時間才能將更大的 page 內容從硬碟搬至記憶體 如果程式用不到這麼大的 page,那麼空間就被浪費了,且也會造成 page fragment,降低 page 的使用效率 總和以上原因,現代處理器都支持大小可變的 page,由作業系統負責管理,根據程式的特點選用不同大小的 page,最大程度地利用 TLB 有限的空間,並降低 page fragment 在 TLB 中會有相對應的設定可以調整映射的 page 大小 因為記憶體的存取速度相對於 CPU 的執行速度來說非常慢,因此 TLB 通常只會採用 Write-back 的方式設計,且因為 TLB entry 中 tag 和 data 等欄位是不會變動的,因此當發生 TLB miss,需要將 TLB entry swap out 時,只需要將 dirty bit (執行 store 指令時會被更新) 和 access bit (執行 load/store 指令時會被更新) 寫回 PTE 中即可 TLB miss 發生的情況: Page 並不在記憶體中,因此也不在 TLB 中 Page 在記憶體中,page table 中也有對應的 PTE,但這個 PTE 並沒有被 cache 在 TLB 中 Page 在記憶體中,page table 中也有對應的 PTE,這個 PTE 也曾經存在 TLB 中,但是因為先前的 TLB miss,因此被替換出來了 TLB miss 時,TLB entry 的替換策略: LRU (Least Recently Used) Random:如同 cache,使用一個 counter,每個 cycle 都會 + 1,每次 TLB miss 要替換 TLB entry 時,就根據當下 counter 的值決定是哪個 entry 要被替換 LRU 比較難實現,所以通常會採用 Random 的替換策略,實做也比較簡單 如果 TLB 採用 Write-back,TLB entry 中的 dirty 和 access bits 就有可能跟 PTE 的內容不同步,如果 page 要被 swap out 的時候,作業系統會無法即時得知究竟 page 是否 dirty,以及是否有被 accessed 過 直觀解法:每次發生 page fault 要 swap page 的時候,先將 TLB entries flush 至 PTE 缺點:需要耗費額外的時間 flush TLB 另類解法:作業系統可以認為,有在 TLB 中被 cached 對應的 pages 都是正在使用的,因此不能將其 swap out 需要作業系統自行維護一張表,紀錄哪些 PTE 有被 cached 在 TLB 中,且為 valid 的 不過這種設計並不常見 如果系統中有 D-Cache,page 也是 dirt 的,那麼 page 被更動的內容也有可能還存在 D-Cache 中,因此在 page swap out 前也必須先 flush D-Cache 3.4.2 - Cache 的設計 兩種 caches: ...

2025/02/27 · 7 分鐘 · 1362 字 · Frank Chang

<超標量處理器概覽> 第 4 章 - 分支預測 (Part 1)

4.1 - 概述 分支預測和 Cache 左右著 CPU 的效能,對於 superscalar CPU 來說,準確度高的分支預測更為重要 在一般的 RISC 指令集中,分支指令包含兩個要素: 方向: 分支指令的方向只有兩種:跳轉 (taken),或是不跳轉 (not taken) 有些跳轉指令是無條件執行的 (e.g. jmp 指令),有些跳轉指令則是需要根據指令中攜帶的條件是否成立來決定是否發生跳轉 (e.g. beq 指令) 目標位址: 對於一般的 RISC 指令集,目標位址在指令中有兩種形式: 直接跳轉 (direct): 目標位址 = 當前分支指令 (或分支指令的下一條指令) 的 PC 值 + immediate PC offset 由於指令通常只有 32/64 bits,因此 immediate PC offset 的值範圍也就有限,因此也限制了直接跳轉能夠跳轉的範圍 因為 immediate PC offset 值是 encode 在分支指令中,因此在 pipeline 的 decode stage 就可以直接將 immediate PC offset 給解析出來,因此這種類型的指令是很容易進行分支預測的 這種跳轉指令的執行效能也比較好 間接跳轉 (indirect): 目標位址是來自於 register 的內容,由於 register 是 32/64 bits,因此可以跳轉到任何位址 由於跳轉位址來自於 register,因此此類的分支指令的目標位址需要等待一段時間才能獲得 (e.g. 要等到 pipeline 的 execute stage) 在確認目標位址前進到 pipeline 的指令,有可能都會是無效的 (if taken),因此增大了 mis-prediction penalty 且由於 register 的內容是會動態變化的,因此這類的分支指令很難對目標位址進行預測 不過慶幸的是,這類指令通常都是 call 或是 return 類型的指令,這類指令都有很強的規律性,是容易被預測的 MIPS R3000 只使用了 5 級的 pipeline,在第二個階段的 decode stage,就可以得到分支指令跳轉的目標位址,即使發生了跳轉 (taken),也只需要丟棄一道仍在 fetch stage 的指令,misprediction penalty 並不高 ...

2025/02/28 · 10 分鐘 · 2080 字 · Frank Chang

<超標量處理器概覽> 第 4 章 - 分支預測 (Part 2)

4.3 - 分支指令的目標位址預測 分支指令的目標位址可以分為兩種: 直接跳轉 (direct): 對於直接跳轉指令 (e.g. RISC-V 的 beq、jal、lui 指令),它的跳轉 offset 是以 immediate value 的方式 encode 在 opcode 中 (有可能是 PC-relative,也有可能不是),所以它的目標位址是固定的,只要記錄這條分支指令目標位址即可 當再次遇到這條分支指令時,如果分支預測結果是 taken,那麼目標位址就可以直接使用先前所記錄的值 間接跳轉 (indirect): 對於間接跳轉指令 (e.g. RISC-V 的 jalr 指令),由於它的目標位址來自於暫存器,而暫存器的值是有可能一直變化的,所以對間接跳轉指令來說,要預測目標位址並不是一件容易的事情 然而慶幸的是,程式中大部份的間接跳轉指令都是用來呼叫函式的,也就是 call 和 return;這種目標位址是有規律的,因此可以對其進行預測 4.3.1 - 直接跳轉類型的分支預測 對於直接跳轉類型的分支指令 (假設是 PC-relative),其目標位址有兩種情況: 當分支指令 not taken 時: 目標位址 = 當前分支指令的 PC 值 + sizeof(fetch group) e.g. PC + 4 當分支指令 taken 時: 目標位址 = 當前分支指令的 PC 值 + signed extended offset e.g. PC + offset ...

2025/03/14 · 8 分鐘 · 1624 字 · Frank Chang

<超標量處理器概覽> 第 6 章 - 指令解碼

在 pipeline 中,decode stage 的任務是將指令中的資訊提取出來,CPU 使用這些資訊控制後續的 pipeline 來執行這條指令 影響 decode 的複雜度因素有: 指令集的複雜度: CISC vs. RISC 每個 cycle 可以 decode 的指令個數: 每個 cycle 可以 decode N 條指令,那就需要 N 個 decode 電路 6.1 - 指令緩存 現代處理器可以在 fetch stage 從 I-Cache 讀出大於每個 cycle 可以 decode 指令個數的指令,因此需要在 fetch stage 和 decode stage 之間加一個 buffer,用來將 I-Cache 讀出的所有指令保存起來,這個 buffer 就稱為 Instruction Buffer Fetch stage 最終會輸出兩個主要的內容給 Instruction Buffer: 從 I-Cache 讀出的 N 條指令 (並非所有指令都是有效的) 有效的指令個數 1 instruction fetch 位址不是 cache aligned 時,或是 fetch group 中包含預測為 taken 的指令,會導致 fetch stage 沒辦法寫入 N 條指令進 Instruction Buffer 此時需要告知 Instruction Buffer,有效的指令個數 現在 superscalar CPU 需要 Instruction Buffer 的原因: Superscalar CPU 可以每個 cycle 可以 fetch 的指令個數大於每個 cycle 可以 decode 的指令個數,這樣即使在發生 I-Cache miss 時,Instruction Buffer 中仍有可能還有保存尚未 decode 的指令,因此不需要 stall pipeline,可以繼續 decode 指令,增加 CPU 的性能 Superscalar CPU 中即使每個 cycle 可以 decode 的指令個數與每個 cycle 所 fetch 的指令個數相等,在 decode stage 仍會有一些特殊的指令需要處理,導致在 fetch stage 所 fetch 的指令沒有辦法全部被 decode 如 ARM 的 multiply-accumulate 指令 (UMAAL RdLo, RdHi, Rn, Rm),會有兩個 destination registers,為了減少對 register renaming 的影響,會將其拆分成兩條普通的指令,每條指令只有一個 destination register 因此,如果在 decode stage 沒有特別的處理,會導致 decode 的指令個數大於 fetch 指令的個數,但後續的 pipeline 都是依照原先的指令個數來設計的,不可能因為這些不常見的指令而增加後續 pipeline 的處理能力 (因為會增加硬體面積,且使用率也不高) 為了解決此問題,就需要加入 Instruction Buffer,讓 multiply-accumulate 後面的指令,可以等到下一個 cycle 再 decode 由於 Instruction Buffer 可以在一個 cycle 內寫入多條的指令,也可以讀出多條的指令,因此也是一個 multi-port 的 FIFIO;但在實際設計上,並不會使用真的 multi-port 的 SRAM 來實現這樣的 FIFO,而是會採用 interleaving 的方式 (參考:2.3.1 - True Multi-port),使用多個 single-port 的 SRAM 來實現,從而避免使用 multi-port SRAM 所導致的硬體速度上的限制 6.2 - 一般情況 ARM 的 CPSR,只有 4 個 bits (N、C、Z、V),但其他的暫存器都是 32 bits 的;如果將 CPSR 跟其他的暫存器統一對待,會造成很多暫存器無法有效的被利用,因為 32 bits 的暫存器,只存了 4 bits 的資料 因此,一般都是將 CPSR 單獨處理,對 CPSR 單獨使用一套 register renaming 的流程,這樣就可以根據 CPSR 的特性來訂製 register renaming 的流程 且考慮到條件執行的指令只是少部份,所以所使用的 register file 可以很小,例如只需只用 16 個 physical registers 就足夠了 指令所攜帶的 source registers 和 destination registers 的個數直接決定了 register renaming 電路在實現上的難易度: 像是 register renaming mapping tables 的 ports 數、指令間相關性檢查電路的複雜度 由於 RISC 架構的指令比較整齊劃一,很容易解析出指令中的 opcode 和 operands,在 decode stage 產生的 pipeline 控制訊號也比較少,因此 RISC 架構的 instruction decoding 通常都可以在 1 個 cycle 完成 一般情況下,RISC 處理器在 decode stage 完成的任務可以概括為: What type:例如指令是算術指令還是分支指令 What operation:例如當指令是算術指令時,是進行什麼運算;是分支指令時,它的跳轉條件是什麼樣的 What resource:例如對算術指令時來說,其 source 和 destination registers 是哪些,有沒有 immediate value 6.3 - 特殊情況 即使在 RISC 指令集中,也存在一些特殊的指令;這些指令不能按照一般的方法處理 例如:ARM 的 LDM / STM 指令,需要多個 cycles 才能完成;而且它們的 source 和 destination registers 有多個,如果在 superscalar CPU 中對它們跟普通指令一樣來處理的話,會需要增加 register renaming mapping table、issue queue 和 ROB 所需的 ports 數,增加硬體的面積,並降低處理效能 因此在 superscalar CPU 中,並不會直接處理 LDM / STM 這樣的指令,而是會將其轉換為多條普通的指令 (µops),每條普通的指令就是一般的 load / store 指令,這樣就可以用普通指令的方式來處理 6.3.1 - 分支指令的處理 先前提到,採用 checkpoint 的方式對 mis-prediction 的分支指令恢復 CPU 的狀態,為了減少分支指令編號分配電路的複雜度,需要限制每個 cycle 能 decode 的分支指令個數,例如每個 cycle 只能 decode 一條分支指令 (參考:4.4 - 分支預測失敗時的恢復) 但是,每個 cycle 從 Instruction Buffer 讀取的指令中,有可能存在多條的分支指令,需要在 decode stage 做特別的處理 簡單的作法: ...

2025/03/23 · 5 分鐘 · 913 字 · Frank Chang

<超標量處理器概覽> 第 7 章 - 暫存器重命名

7.1 - 概述 程式中不同指令的相關性 (dependency) 可以分類為: 數據相關性 (data dependency),包含以下幾種類型: WAW (Write After Write) dependency,i.e. output dependence: 兩條指令都將結果寫到同一個 destination register 中 WAR (Write After Read) dependency,i.e. anti-dependence: 一條指令的 destination register 和它前面某條指令的 source register 相同 RAW (Read After Write) dependency,i.e. true dependence: 一條指令的 source register 和它前面某條指令的 destination register 相同 只有 RAW 是真的相關性, WAR 和 RAW 可以透過 register renaming 來解決 記憶體數據相關性 (memory data dependency): Load 和 store 指令之間的相關性,代表 load 和 store 指令都存取到同一個位址 同樣也分為 WAW、WAR、RAW dependencies 控制相關性 (control dependency): ...

2025/03/27 · 21 分鐘 · 4289 字 · Frank Chang

<超標量處理器概覽> 第 8 章 - 發射 (Part 1)

8.1 - 概述 Issue 就是將符合一定條件的指令從 Issue Queue 中選出來,並送到 FU (Function Unit) 中執行的過程 Issue Queue 會依照一定的規則,選擇那些 source registers 都已經準備好的指令,將其送到 FU 中執行,這個過程就稱為:Issue Issue Queue 也被稱為 Reservation Station 對於 in-order core,指令會按照程式原始順序加進 Issue Queue 中,此時 Issue Queue 就相當於一個 FIFO 對於 out-of-order core,只有少數指令,如 store 及分支指令,才會採用 in-order 的方式執行,對其他大部分的指令,都是採用 out-of-order 的方式執行 指令到了 Issue Queue 後,只要 Issue Queue 中任一條指令的 operands 都準備好了,且滿足 issue 的條件,就可以將其送到 FU 中執行 Issue Queue 設計的好壞,會直接影響處理器的 concurrency Issue stage 的硬體比較複雜,一般它都在 critical path 上,直接影響 CPU 的 cycle time ...

2025/04/09 · 11 分鐘 · 2236 字 · Frank Chang

<超標量處理器概覽> 第 8 章 - 發射 (Part 2)

8.5 - 喚醒 (Wake up) 8.5.1 - 單週期指令的喚醒 Wake up 是指被 select 電路選中的指令將其執行完後,將其 destination register 和 Issue Queue 中所有的 source registers 編號做比較,並將相同編號的 source registers 標記為 ready 的過程 因為需要將被選中指令的 destination register 編號需要傳遞到 Issue Queue 中的所有 entries,當 Issue Queue 容量比較大,或是 Issue Queue 的個數比較多時,這個編號就需要走很長的路徑 一般情況下,select 電路的個數等同於 issue width 以下是 Issue width = 4 的 wake-up 電路 (只包含一個 Issue Queue 的 entry,且所有 select 電路共用同一個 Issue Queue): SrcL /SrcR:第一、第二個 source register 的編號 ValL / ValR:指令是否存在第一、第二個 source register RdyL / RdyR:第一、第二個 source register 是否準備好 Dest:Destination register 的編號 Issued:指令是否已經被 issued 出去 當指令準備好,並被 select 電路選中時,此時該指令不一定會馬上被 issued 出去 (e.g. 一條指令使用了 load 指令的結果,即使其被 select 電路選中,也不可以馬上離開 Issue Queue),因此需要透過 Issued 記錄該指令是否已經被 issued 了 如果已經被 issued,select 電路就不會重複選到該指令 當指令準備好時,就會向 select 電路送 request 訊號,請求被仲裁 Select 電路會選擇根據是否選擇了該指令,送出 grant 訊號 四個 select 電路同時間只會有一個 grant 訊號是 valid 的 如果一條指令被 granted,那麼就會將其 Dest 送到 tag bus 上,以便 broadcast 給所有的 Issue Queue entries 實務上,為了提供速度,需要減少 Issue Queue 的容量,因此可以使用多個容量較小的 Issue Queue ...

2025/04/19 · 13 分鐘 · 2643 字 · Frank Chang

<超標量處理器概覽> 第 9 章 - 執行

9.1 - 概述 FU 的個數決定了每個 cycle 最大可以同時執行的指令個數,也就是 issue width Execute stage 另一個重要的部份就是 bypassing network,其負責將 FU 的運算結果送到其他需要它的地方,像是 physical register file (PRF)、其他 FU 的輸入端、store buffer 等 隨著每個 cycle 可以同時執行的指令個數的增多,bypassing network 變得越來越複雜,已經是處理器中速度提昇的一個關鍵部份 在不使用 bypassing network 的情況下,指令的 operands 值可以來自於 PRF (for non-data-capture),或是 payload RAM (for data-capture),每個 FU 都是透過 select 電路將 PRF 或是 payload RAM 串連起來的 每個 select 電路和 PRF (或是 payload RAM) 的 read ports 是一一對應的,每個 FU 和 PRF (或是 payload RAM) 的 read ports 也是一一對應的 因此,PRF 總共需要的 read ports 個數與 issue width 是直接相關的;如果對處理器追求更大的 issue width,就代表著 PRF 需要更多的 read ports,反而會限制了處理器的執行速度,現代處理器多會採用 cluster 架構來解決這個矛盾 Payload RAM 由於需要與 Issue Queue 綁定在一起,使用 distributed Issue Queue 可以減少 payload RAM read ports 的需求 9.2 - FU 的類型 9.2.1 - ALU ALU (Arithmetic and Logic Unit) 通常負責:整數加減法、shift、簡單的乘除法、資料搬移 (e.g. mov、byte-swap 指令)、分支指令目標位址的計算、記憶體存取位址的計算 很多處理器在 ALU 中也實現了比較簡單的乘法功能,用來支持乘法指令 不過為了追求比較高的處理效能,高性能處理器通常選擇將乘法器單獨使用一個 FU 來實現,並在這個 FU 中實現乘累加的功能 有些處理器基於功耗和成本的考量,會將整數類型的乘法交由浮點數運算的 FU 來運算 整數轉成浮點數 → 浮點數乘法 → 浮點數轉為整數 指令的 latency 會變長,但較省面積和功耗,Intel Atom CPU 就採用了此設計 9.2.2 - AGU AGU (Address Generate Unit) 用來計算記憶體存取位址,如 load/store 指令 在一般 pipeline 處理器中,記憶體的存取位址都是交由 ALU 來計算,但是在 superscalar CPU 中,由於需要同時執行多條的指令,記憶體存取指令的執行效率直接影響了處理器的性能,所以通常會單獨使用一個 FU 來計算其位址 9.2.3 - BRU BRU (Branch Unit) 負責處理 control flow 類型的指令,如 branch、jump、call 和 return 類型的指令,BRU 負責將這些指令所攜帶的目標位址計算出來,並根據一定的條件決定是否使用這些位址;同時,在這個 FU 中還會對分支預測與否正確進行檢查,一旦發現 mis-prediction,就需要啟動相對硬的恢復機制 ARM 和 PowerPC 等處理器在指令中的編碼加上了 condition code,根據 condition code 來決定指令是否執行 優點: ...

2025/04/28 · 15 分鐘 · 3034 字 · Frank Chang

<超標量處理器概覽> 第 10 章 - 提交

10.1 - 概述 在 out-of-order superscalar CPU 中,為了保持程式執行順序的一致性,一般通常都會在 pipeline 的最後增加一個 commit stage 當指令抵達 commit stage 時,會將這條指令在 ROB 中的 entry 標記為 complete 此時只代表這個指令已經計算完成,不代表可以離開 pipeline (i.e. retire) 指令進到 commit stage 並不代表它一定是正確的,有可能這條指令處在 mis-prediction 或是 exception 的路徑上,最後需要從 pipeline 中被 flushed 掉 只有當這條指令之前的指令都已經 retire 了,且這條指令已經是 complete 的狀態,才可以 retire 並離開 pipeline 在一條指令 retire 前,它的狀態都是 speculative 的,只有當這條指令真的 retire 後,才可以將它的狀態更新到 CPU 的 architecture state 對一個 N-way 的 superscalar,因為每個 cycle 最少可以 fetch N 條指令進 pipeline 中,pipeline 至少也需要 retire N 條指令,才能確保 pipeline 不會被堵塞 10.2 - ROB 10.2.1 - 一般架構 ROB 本質上是一個 FIFO,ROB 中儲存了指令的相關訊息,例如:一條指令的類型、結果、destination register 和 exception 的類型等 ...

2025/05/04 · 11 分鐘 · 2247 字 · Frank Chang

<超標量處理器概覽> 第 11 章 - 真實世界的例子:Alpha 21264 處理器

11.1 - 概述 DEC 的 Alpha 21264 是 superscalar CPU 的一個典範,其為 4-way out-of-order superscalar CPU,工作頻率是 466 ~ 667 MHz,benchmark:SPECint95 - 40、SPECfp95 - 86;與同時期其他的處理器 benchmark 對比: Alpha 21264 的 pipeline 最多同時支持 80 條指令,以及 80 個 checkpoints,因此對於 branch mis-prediction、exception、interrupt,Alpha 21264 都可以快速地恢復 CPU 狀態 Alpha 21264 的分支預測器實現了基於局部歷史 (Local prediction) 和基於全局歷史 (Global prediction) 兩種預測方式,並根據程式的執行情況,動態選擇預測率最高的方法,這就像是兩種分支預測方式在進行競爭一樣 對於 load/store 指令,Alpha 21264 採用了 Speculative Memory Disambiguation 和 Load hit/miss Prediction Alpha 21264 採用 7-stage pipeline,比較短的 pipeline 使 branch mis-prediction 發生時的 mis-penalty 比較低,從而提高處理器的效率: ...

2025/05/10 · 15 分鐘 · 3101 字 · Frank Chang