隱藏記憶體延遲 (Hiding Memory Latency):Banks 與 Channels
重點總覽 (Overview)
DRAM 速度遠慢於處理器,光靠 burst 還不夠。現代 DRAM 用三層平行化堆出頻寬:bursts(章節 06-Performance-Considerations/01-Memory-Coalescing)、banks、channels。本節說明後兩者,以及為何「拉高 occupancy」不只是隱藏運算 pipeline 延遲,也是隱藏 DRAM 延遲的關鍵。
| 概念 | 角色 | 關鍵數字 / 規則 |
|---|---|---|
| Channel | 一個 memory controller + bus,連接一組 banks 到處理器 | 真實系統 1–8 channels |
| Bank | channel 下的一組 DRAM cell array + sense amplifier | 每 channel 需 > R 個 bank(R = latency/transfer 比) |
| DDR bus | 每 clock 傳兩次(rising + falling edge) | 64-bit @1GHz = 8B × 2 × 1GHz = 16 GB/s |
| Bank-level overlap | 在某 bank 等延遲時,另一 bank 並行存取 | 單 bank 利用率僅 1/(R+1) |
| Interleaved distribution | 硬體把連續位址灑遍所有 channel/bank | 先填滿一個 bank 的 burst,再換下一 channel |
| Occupancy ↔ 頻寬 | 夠多 thread 同時發出存取,才餵飽 banks/channels | 高 occupancy 同時隱藏 pipeline + DRAM 延遲 |
要把 DRAM 頻寬跑滿,三件事缺一不可:(1) 每筆存取是 coalesced;(2) 存取平均分散到各 channel 與 bank;(3) 有夠多 thread(高 occupancy)同時發出存取。
DRAM 的平行組織:Banks 與 Channels (Banks and Channels)
- Channel:一個 memory controller,帶一條 bus 連接一組 DRAM banks 到處理器。
- Bank:包含一塊 DRAM cell array、sense amplifiers,以及把 burst 資料送上 bus 的介面。
- bursting 只是「一次存取拿一段連續資料」;banks/channels 才提供跨存取的平行度。
Processor
┌──────┬──────┬──────┬──────┐
Ch0 Ch1 Ch2 Ch3 ← 每個 channel = controller + bus
│ │ │ │
[bank0][bank0][bank0][bank0]
[bank1][bank1][bank1][bank1] ← 多個 bank 掛在同一條 bus 上
[bank2][bank2][bank2][bank2]
[bank3][bank3][bank3][bank3]
真實系統通常 1–8 channels,且每 channel 掛大量banks(遠不止圖中 4 個)。圖示只是 toy example。
DDR 頻寬計算 (DDR Bandwidth)
- bus 頻寬 = bus 寬度 × clock frequency。
- DDR (double data rate) bus 每個 clock cycle 傳輸兩次:rising edge 一次、falling edge 一次。
公式:
頻寬 = 寬度(B) × 2 × clock(GHz)
例:64-bit (= 8 B) DDR @ 1 GHz →8 × 2 × 1= 16 GB/s
| 裝置 | 典型需求頻寬 | 以 16 GB/s 單 channel 計,需要的 channel 數 |
|---|---|---|
| 現代 CPU | ≥ 32 GB/s | 2 channels |
| 現代 GPU | ≥ 256 GB/s | 16 channels |
公式:
channels 需求 = 目標頻寬 / 單 channel 頻寬(GPU:256 / 16 = 16)
為何需要多個 Bank:Latency Hiding (Why Multiple Banks)
每筆 DRAM 存取 = 長延遲(decoder 啟動 cell + 電荷分享到 sense amplifier)+短資料傳輸(burst 上 bus)。延遲遠大於傳輸時間。
單 bank(Fig 6.8A):bus 大量閒置
bank0: [==== latency ====][burst][==== latency ====][burst]
bus : ^^^^^ ^^^^^ ← 利用率極低
兩 bank(Fig 6.8B):延遲互相重疊
bank0: [==== latency ====][burst]
bank1: [==== latency ====][burst]
bus : ^^^^^^^^^^^ ← bus 幾乎連續忙碌
- 設 R = cell array 存取延遲 / 資料傳輸時間。
- 單 bank 利用率 =
1/(R+1)。例:R = 20 →1/21≈ 4.8%;16 GB/s channel 實際只送 ~0.76 GB/s(不可接受)。 - 要跑滿 bus,至少需要 R + 1 個 bank(R = 20 → 至少 21 banks)。
公式:
單 bank 利用率 = 1/(R+1);跑滿 bus 所需 bank 數 ≥ R + 1
實務上 bank 數要比 R + 1 更多,原因有二:
- 降低 bank conflict:多筆同時存取打到同一 bank 時,因每 bank 一次只能服務一筆,延遲無法重疊。bank 越多,撞同一 bank 的機率越低。
- 容量限制:單一 cell array 大小受延遲與良率限制,要支撐整體記憶體容量本來就需要很多 bank。
Interleaved Data Distribution(交錯式資料分佈)
陣列元素由硬體自動灑到各 channel/bank。策略:先填滿某 bank 在某 channel 的一個 burst,再換下一個 channel;channel 用完一輪後才進到下一個 bank。
Toy example(burst size = 2 elements = 8 bytes):
Ch0 Ch1 Ch2 Ch3
bank0: M[0],M[1] M[2],M[3] M[4],M[5] M[6],M[7]
bank1: M[8],M[9] M[10],M[11] M[12],M[13] M[14],M[15]
(然後 wrap 回 Ch0/bank0:M[16],M[17] ...)
- 連續位址先走遍 4 個 channel(最大化 channel 平行),再跳 bank。
- 好處:即使是小陣列也能均勻散開。本例只要 ≥ 16 元素,就用到全部 channel 與 bank。
因為 distribution 是「channel 優先」,coalesced 連續存取天然會被拆散到不同 channel → 同時得到 burst 利用、channel 平行、bank 平行三重好處。
Thread 平行 ↔ DRAM 平行的共生關係 (Occupancy Hides DRAM Latency)
用 2×2 thread block + 2×2 tile 的 tiled 矩陣乘法(05-Memory-Architecture-And-Data-Locality/02-Tiling-and-Tiled-Matrix-Multiplication)觀察 phase 與 DRAM 的互動:
| Phase | 4 個 block 載入的 M 元素落在 | 平行度 |
|---|---|---|
| Phase 0 | channel 0 的兩個 bank + channel 2 的兩個 bank | 4 筆 coalesced 存取並行 |
| Phase 1 | channel 1 的 bank + channel 3 的 bank | 並行 |
Block0,0與Block0,1載入相同的 M 元素 → 若執行時序夠接近,GPU cache 會把它們合併成一次 DRAM 存取(GPU cache 主要用途即在此)。- 共生關係:
- DRAM 頻寬要被用滿 → 需要很多 thread 同時存取。
- 裝置運算吞吐要高 → 需要善用 DRAM 的 banks/channels 平行結構。
- 若同時執行的 thread 全擠在同一個 channel → 頻寬與整體速度大幅下降。
這是 maximizing occupancy 的第二個好處:04-Compute-Architecture-And-Scheduling/03-Resource-Partitioning-and-Occupancy 提到高 occupancy 隱藏 core pipeline 延遲;本節指出它同時確保發出足夠多的記憶體存取,去隱藏 DRAM 延遲、餵滿頻寬。
burst size 越大,需要更大的矩陣才能用滿所有 channel 的頻寬(小資料無法鋪滿所有 bank/channel)。
考試/面試重點 (Exam / Test Patterns)
| 情境 / 關鍵字 | 答案 / 技巧 |
|---|---|
| DDR bus 頻寬怎麼算? | 寬度(B) × 2 × clock;DDR 每 cycle 兩次。64-bit@1GHz = 16 GB/s |
| GPU 需 256 GB/s,單 channel 16 GB/s,要幾個 channel? | 256 / 16 = 16 channels |
| 單 bank 為何浪費頻寬?利用率? | latency ≫ transfer;利用率 = 1/(R+1),R=20 → 4.8% |
| 要跑滿 bus 至少幾個 bank? | ≥ R + 1(R=20 → ≥ 21),實務上更多 |
| 為何 bank 要比 R+1 多? | (1) 降低 bank conflict 機率 (2) 容量需求 |
| bank conflict 是什麼? | 多筆存取打到同一 bank;一次只服務一筆 → 延遲無法重疊 |
| Interleaved distribution 順序? | channel 優先(填滿一 bank burst → 換 channel → 用完一輪才換 bank) |
| 「隱藏 memory latency」靠什麼? | banks/channels 平行 + 高 occupancy(足夠 thread 同時發存取) |
| Occupancy 的兩個好處? | 隱藏 core pipeline 延遲 + 隱藏 DRAM 延遲(餵滿頻寬) |
| 跑滿 DRAM 頻寬三條件? | coalesced + 平均分散到 channel/bank + 高 occupancy |
Related Notes
- 06-Performance-Considerations/01-Memory-Coalescing
- 06-Performance-Considerations/03-Thread-Coarsening
- 06-Performance-Considerations/04-Optimization-Checklist-and-Bottlenecks
- 04-Compute-Architecture-And-Scheduling/03-Resource-Partitioning-and-Occupancy
- 05-Memory-Architecture-And-Data-Locality/02-Tiling-and-Tiled-Matrix-Multiplication
- 22-Advanced-Practices-And-Future-Evolution/03-Memory-Bandwidth-and-Compute-Throughput