CPU的緩存越來越大,但單端口SRAM的訪問速度跟不上處理器的發(fā)射寬度。多緩存組(Multi-Banking)技術(shù)把一個大緩存拆成多個獨立的小塊,讓它們并行工作。
1. 單端口緩存的瓶頸
現(xiàn)代超標(biāo)量處理器每周期可以發(fā)射多條內(nèi)存指令。比如Intel Core i7每周期能發(fā)射2個load和1個store。但如果緩存是單端口的,這些請求必須排隊串行處理,處理器只能干等。
更糟的是功耗。單端口緩存每次訪問都要激活整個存儲陣列,哪怕只讀4字節(jié)。這就像為了開一盞燈,把整個樓的電閘都合上。
2. Bank化怎么破局
把緩存切成多個獨立的Bank,每個Bank有自己的端口和控制邏輯。只要訪問的是不同Bank,就能并行處理。
2.1 地址映射策略
最簡單的映射是取模:
假設(shè)64字節(jié)塊、4個Bank:
- 地址0x0000 → Bank 0
- 地址0x0040 → Bank 1
- 地址0x0080 → Bank 2
- 地址0x00C0 → Bank 3
- 地址0x0100 → Bank 0(循環(huán))
這種交錯(Interleaving)讓連續(xù)地址分散到不同Bank,最大化并行性。
2.2 實際芯片的Bank配置
| 處理器 | 緩存層級 | Bank數(shù) | 設(shè)計特點 |
|---|---|---|---|
| ARM Cortex-A8[1] | L2 | 1-4可配置 | 根據(jù)負(fù)載動態(tài)啟用,平衡帶寬與功耗 |
| Intel Core i7[2] | L1D | 4 | 支持每周期2次訪問 |
| Intel Core i7[2] | L2 | 8 | 多核共享,更高并行度 |
| AMD Opteron[3] | L1D | 8 | 每Bank 64位寬,總線512位 |
| NVIDIA GPU | L2 | 16+ | 高并行,支持warp級訪問 |
ARM Cortex-A8的L2緩存特別有意思——它支持1到4個Bank的軟件可配置[1]。低負(fù)載時只開1個Bank省電,高負(fù)載時全開4個Bank提速。
3. Bank沖突:并行化的天敵
Bank化的前提是訪問落在不同Bank。如果兩個請求命中同一個Bank,就會沖突,必須串行處理。
3.1 沖突的性能代價
ISCA 2015的一項研究[4][5]測量了Bank沖突的影響:
- 測試配置:4周期發(fā)射到執(zhí)行延遲的亂序處理器,雙發(fā)射load能力
- Bank配置:4-Bank L1D緩存(類似Intel Core i7)
- 結(jié)果:Bank沖突導(dǎo)致平均4.7%性能損失(相比理想雙端口緩存)
- 微指令重放:因沖突重放的微指令占總發(fā)射的5.1%
4.7%聽起來不多,但在高性能計算中,每1%都很珍貴。
3.2 什么代碼容易沖突
Stride = Block_Size × N:
// 假設(shè)64字節(jié)塊,4個Bank
// Stride = 256字節(jié)(0x100)
for (int i = 0; i < N; i += 64) {
sum += array[i]; // 每次訪問Bank 0
}
這種代碼所有訪問都落在Bank 0,其他Bank閑置,性能退化為單Bank。
矩陣轉(zhuǎn)置:
// 行優(yōu)先存儲,按列訪問
for (int j = 0; j < cols; j++) {
for (int i = 0; i < rows; i++) {
dst[j][i] = src[i][j]; // Stride = 行大小
}
}
如果行大小恰好是Bank數(shù)的倍數(shù),就會產(chǎn)生嚴(yán)重沖突。
3.3 緩解沖突的方法
增加Bank數(shù):
從4 Bank增加到8 Bank,沖突概率理論上減半。但面積和功耗也增加。
非線性映射:
用哈希函數(shù)替代簡單取模:
這種XOR哈希能打亂規(guī)律性訪問模式,減少沖突。
軟件層面的Loop Interchange:
編譯器優(yōu)化可以把:
// 原始代碼 - 可能沖突
for (j) for (i) dst[j][i] = src[i][j];
變成:
// 優(yōu)化后 - 連續(xù)訪問
for (i) for (j) dst[j][i] = src[i][j];
4. 硬件實現(xiàn)細(xì)節(jié)
4.1 Bank選擇邏輯
地址的低位直接選擇Bank,高位用于Tag比較和行內(nèi)偏移。
以Intel Core i7的L1D為例(4 Bank,64字節(jié)行):
| 地址位 | 用途 |
|---|---|
| [5:0] | 塊內(nèi)偏移(64字節(jié)) |
| [7:6] | Bank選擇(4 Bank) |
| [31:8] | Tag比較 |
這樣Bank選擇可以在1個周期內(nèi)完成,不增加關(guān)鍵路徑延遲。
4.2 多端口的假象
多Bank不是真正的多端口。每個Bank仍然是單端口,只是多個Bank可以并行。
如果兩個請求命中同一Bank,必須仲裁。常用策略:
- 輪詢(Round-Robin):公平但可能延遲關(guān)鍵路徑
- 優(yōu)先級:老請求優(yōu)先,或load優(yōu)先于store
- 年齡:最老的請求優(yōu)先,保證前進(jìn)
4.3 面積與功耗權(quán)衡
| Bank數(shù) | 控制邏輯面積 | 動態(tài)功耗 | 峰值帶寬 |
|---|---|---|---|
| 1 | 1x | 1x | 1x |
| 4 | ~1.3x | 0.6x(相同訪問模式) | 4x |
| 8 | ~1.6x | 0.4x | 8x |
注意動態(tài)功耗列。多Bank能降低功耗,因為每次只激活一個Bank的小陣列,而不是整個大陣列。
ARM Cortex-A8的實測數(shù)據(jù)[1]:4 Bank配置比1 Bank節(jié)省約35%動態(tài)功耗(相同負(fù)載下)。
5. 與亂序執(zhí)行的協(xié)同
多Bank緩存和亂序執(zhí)行處理器是絕配。
5.1 動態(tài)調(diào)度避免沖突
亂序執(zhí)行核可以重排指令,把訪問不同Bank的load提前,沖突的推遲。
Intel Core i7的Memory Disambiguator會預(yù)測load-store別名,同時考慮Bank沖突,選擇最優(yōu)發(fā)射順序。
5.2 Schedule Shifting優(yōu)化
ISCA 2015提出的Schedule Shifting技術(shù)[5]:
當(dāng)雙發(fā)射兩個load時,讓第二個load的依賴指令晚一個周期發(fā)射。這樣即使第二個load遇到Bank沖突,額外的周期可以被掩蓋。
效果:
- 恢復(fù)2.8%的性能損失(從4.7%降到1.9%)
- 減少74.8%因Bank沖突導(dǎo)致的微指令重放
實現(xiàn)成本極低——只需要在調(diào)度器中加一個周期的偏移。
6. GPU中的極致Bank化
GPU對Bank化的需求比CPU更強(qiáng)烈。
6.1 Warp級并行訪問
一個Warp(32線程)同時執(zhí)行,每個線程可能訪問不同地址。如果這32個地址分散在32個Bank,可以一次完成;如果都擠在一個Bank,需要32個周期。
6.2 Shared Memory的Bank沖突
NVIDIA GPU的Shared Memory有32個Bank(計算能力3.0+)。
無沖突訪問:
// 每個線程訪問不同Bank
int val = shared[threadIdx.x]; // Bank = threadIdx.x % 32
沖突訪問:
// 所有線程訪問Bank 0
int val = shared[0]; // 32周期串行
部分沖突:
// Stride=2,線程0,2,4...訪問Bank 0,2,4...(偶數(shù)Bank)
// 線程1,3,5...訪問Bank 1,3,5...(奇數(shù)Bank)
// 需要2周期完成
int val = shared[threadIdx.x * 2];
6.3 廣播機(jī)制
如果32個線程都讀同一個地址,GPU可以廣播,只讀一次分給所有線程。這不算是Bank沖突。
7. 實際調(diào)試:如何檢測Bank沖突
Intel PMU(Performance Monitoring Unit)可以統(tǒng)計:
-
L1D_PEND_MISS.PENDING:L1D pending miss周期 -
L1D_PEND_MISS.FB_FULL:Fill Buffer滿(可能由Bank沖突引起)
ARM Cortex-A8有L2CC寄存器可以監(jiān)控L2 Bank使用情況[1]。
8. 總結(jié)
| 特性 | 單Bank | 多Bank |
|---|---|---|
| 峰值帶寬 | 低 | 高(隨Bank數(shù)線性增長) |
| 訪問延遲 | 固定 | 可能因沖突增加 |
| 功耗效率 | 低(每次激活整個陣列) | 高(只激活一個Bank) |
| 面積開銷 | 低 | 高(控制邏輯復(fù)制) |
| 實現(xiàn)復(fù)雜度 | 簡單 | 需要仲裁和沖突處理 |
多Bank緩存是帶寬和功耗的權(quán)衡藝術(shù):
- Bank數(shù)太少:并行度不夠,容易沖突
- Bank數(shù)太多:面積功耗爆炸,收益遞減
實際設(shè)計的甜點區(qū):
- L1緩存:4-8 Bank
- L2緩存:8-16 Bank
- GPU Shared Memory:32 Bank
理解Bank化,寫代碼時就能避免Stride陷阱,做體系結(jié)構(gòu)設(shè)計時也能做出合理的權(quán)衡。
參考
================================================================================
-
ARM Cortex-A8 Technical Reference Manual. L2 Cache Bank Structure. ? ? ? ?
-
Computer Systems Engineering, SJTU. Multibanked Caches Lecture Notes. ? ?
-
AMD Opteron Processor Data Sheet. Cache banking implementation with 8 banks. ?
-
ISCA 2015. Cost-Effective Speculative Scheduling in High Performance Processors. ?
-
Hal-01193233. Cost-Effective Speculative Scheduling in High Performance Processors (Extended Version). ? ?