多層快取(multilevel cache)
單一快取存在一種張力:你希望它極小、好讓它在一個週期內就被回答,但你又希望它極大、好讓它幾乎從不未命中。一個結構裡無法兩者兼得。解法是不再二選一,而是把好幾個快取疊起來:核心旁一個極小、快得發燙的,由一個較大、稍慢的撐腰,再由一個更大、更慢的撐腰。多層快取就是這個疊層——典型是 L1、L2、L3——每一層用一些速度換取比上一層更多的容量。
存取時,核心先查 L1;若 L1 未命中,查 L2;若 L2 未命中,查 L3;只有 L3 也未命中,請求才去主記憶體。每一層接住從上一層逃掉的未命中中的一份,所以 L1 看到的平均未命中代價很小——大多數 L1 未命中被 L2 迅速接住,而非靠一趟到 DRAM 的長途。L1 通常分成獨立的指令快取與資料快取(頂層的哈佛式分流,好讓核心在同一週期既提取指令、又載入資料值),而 L2、L3 通常是統一的。一個關鍵設計選擇是包含關係:包含式階層在 L2 也保留 L1 內容的副本(一致性較簡單,但複製資料浪費容量),而互斥式階層讓每個區塊只存在一層(有效總容量較大、記帳較複雜)。
多層快取正是 AMAT 公式遞迴得以兌現之處:L1 的未命中代價就是 L2 的 AMAT,依此類推,所以加一個中間層在不拖慢快速 L1 的情況下,大幅降低有效代價。它是每顆現代 CPU 的標準組織。誠實的微妙處:更多層會給一次真正一路到記憶體的未命中增加延遲(你得先查好幾個快取)、並消耗面積與功耗,而在多核心晶片上,最後一層快取通常由各核心共享,這讓它牽扯進超出單核心視角的一致性與爭用問題。儘管如此,對單核心的記憶體速度問題而言,分層快取是核心而決定性的技術。
假設 L1 命中 = 1 週期、L2 命中 = 10、DRAM = 100。L1 未命中率 5%,其中 80% 被 L2 接住,則有效的 L1 未命中代價約為 0.8 x 10 + 0.2 x 100 = 28 週期,而非一律 100——中間層砍掉了平均成本。
疊起來的快取(L1/L2/L3):每層接住上一層的未命中,使平均代價維持低點。
包含式對互斥式是真正的取捨,不是顯而易見:包含簡化一致性(外層知道內層裝什麼)、卻因複製資料浪費容量;互斥讓有效容量最大、卻使記帳複雜。沒有一種選擇普遍「最好」。