標籤/索引/位移切分(tag/index/offset split)
郵局分信時,把地址分成幾段、各司其職地讀:城市決定哪個分揀中心,街道挑路線,門牌號則是街道內最後的投遞。送進快取的記憶體位址也以同樣方式被讀,切成三個欄位、各有獨立工作:位移、索引、標籤。理解這個切分,是讓每一種快取組織豁然開朗的鑰匙。
從低位(最右)往上讀:位移是最底層的位元,選擇快取列內的第幾個位元組(64 位元組的列需要 6 個位移位元,因為 2^6 = 64)。它上面是索引,選擇區塊映射到哪一組(或在直接映射快取裡,哪一個槽);若快取有 2^k 組,就需要 k 個索引位元。剩下的高位是標籤,與列一起存放,查找時拿來比對,確認此刻坐在那組裡的列,真的是你要的區塊,而非剛好共用同一索引的別的區塊。所以查找是:用索引找到那組,比對標籤以偵測命中,再用位移挑出位元組。
這三向切分正是快取快的原因:索引只是位址的某些位元,所以找到候選的那組完全不需搜尋,只有標籤需要比對。它也讓整個設計空間一目了然。每組更多列(更高相聯度)意味平行比對更多標籤、更少索引位元。更大的列意味更多位移位元。兩個索引相同、標籤不同的位址,正是在低相聯度快取裡相撞、造成衝突未命中的那些區塊。值得記住的誠實微妙處:哪些位元當索引、哪些當標籤,是設計選擇,糟糕的選擇會讓存取模式更易相撞——這就是有些快取會把索引位元雜湊以打散碰撞的原因。
一個 32 位元位址送入有 64 位元組列、256 組的快取:第 [5:0] 位是位移(每列 64 位元組),第 [13:6] 位是索引(256 = 2^8 組),第 [31:14] 位是 18 位元的標籤。查找:索引→組、比對標籤、位移→位元組。
位址被讀成 標籤 | 索引 | 位移:索引找到組、標籤確認區塊、位移挑出位元組。
位移位元「絕不」用來選組——它只挑列內的位元組,這正是區塊按列對齊的原因。初學者常犯的錯是某一欄位用了太多或太少位元;三個欄位寬度必須加起來等於整個位址,且各自由快取的幾何固定。