TLB 未命中(TLB miss)
延續便利貼的畫面:TLB 未命中就是訪客問到一個房間、其轉換不在櫃台人員便利貼上的那一刻。現在櫃台人員必須真的翻開那本大目錄、查出來、並把結果抄到便利貼上供下次用。TLB 未命中就是硬體在 TLB 裡找轉換卻沒找到,被迫走上讀分頁表這條較慢的路。
具體來說,TLB 未命中時,該虛擬分頁號未被快取,所以轉換必須從記憶體中的分頁表取得——這個過程叫分頁表走訪(page-table walk)。在許多系統上,專用硬體會自動走訪多層分頁表(每一層碰一次記憶體);在其他系統上,未命中會陷入作業系統的軟體處理常式。無論哪種,找到的對應接著會被裝進 TLB,好讓下次存取該頁時命中。關鍵是:TLB 未命中與分頁錯誤不同:TLB 未命中只是說轉換沒被快取(那頁可能好端端地在 RAM 裡),而分頁錯誤則是說那頁本身根本不在記憶體中。TLB 未命中花幾個到幾十個週期;主要分頁錯誤花數百萬個。
為何重要:TLB 未命中是一項真實、卻常被忽略的效能代價。以散落、足跡龐大的模式跨步走過記憶體的程式碼——碰許多不同的分頁——即使資料快取表現良好,也可能不斷 TLB 未命中,因為資料塞得進快取列,但轉換卻撐爆了 TLB 微小的容量。這正是為何巨型分頁、分塊、與顧及 TLB 的資料佈局,對高效能工作很重要,也是為何量測 TLB 未命中率(而不只是快取未命中率)是認真效能調校的一環。
走訪一個巨大的鏈結串列、其節點散落在數千個分頁上,可能幾乎每個節點都 TLB 未命中——每次未命中觸發一次分頁表走訪——即使每個節點都舒舒服服地常駐在 RAM 裡。
散落而龐大的足跡撐爆 TLB;即使資料在 RAM 裡,轉換仍未命中。
不要把 TLB 未命中與分頁錯誤混為一談。TLB 未命中是轉換的快取未命中(頁可能在 RAM 裡);分頁錯誤是頁不在 RAM 裡。一次存取可能兩者都發生——一次 TLB 未命中,其走訪接著發現一個無效的 PTE,就變成分頁錯誤。