記憶體階層與快取

未命中代價(miss penalty)

假設筆不在你桌上。為此付出的代價不是零、也不是無限——它正好是你起身、走到抽屜、拿到筆、再走回來所花的時間。未命中代價正是如此:一次快取未命中所多花的時間,量的是從下一層把所需的列抓來並交付要多久,超出命中本會花的部分。

具體來說,未命中代價是抵達持有資料那一層的延遲:在 L2 命中的 L1 未命中,只付(較小的)L2 存取時間;連 L2、L3 都未命中、一路到 DRAM 的 L1 未命中,付的是(較大的)主記憶體延遲。這就是多層快取有幫助的原因——它們在較近、中等快速的層級接住許多未命中,而非讓每次未命中都一路掉到記憶體,藉此縮小平均代價。代價通常以 CPU 週期計,對一顆快速核心而言,跑一趟 DRAM 可達數百個週期。

未命中代價是讓未命中變得重要的那個乘數。百分之幾的未命中率聽來無害,直到你把它乘上一百多個週期的代價——那時這百分之幾就能主導整支程式的記憶體時間。平均記憶體存取時間正捕捉了這點,它以未命中代價對未命中率加權。架構師的槓桿是:降低未命中率(區域性、更大或更聰明的快取),或降低代價(加快取層級、增加記憶體頻寬、用亂序執行與預取把未命中和其他工作重疊)。一個誠實的微妙處:在亂序核心上,完整代價不一定全暴露出來,因為當未命中尚未完成時處理器可繼續做不相依的工作——所以程式實際看到的「有效」代價可能比原始延遲小。

命中時間 1 週期、一次到 DRAM 的 L1 未命中花 100 週期時,未命中代價是多出的約 99 週期。加一個能在 10 週期內接住大多數 L1 未命中的 L2,L1 看到的平均代價就朝 10、而非 100 靠近。

未命中多花的時間——下探到真正持有資料那一層的延遲。

在亂序核心上,未命中代價部分被掩蓋:未命中被服務時 CPU 仍跑其他不相依指令,所以「有效」代價可能遠小於原始記憶體延遲。在簡單的循序核心上,它則完整暴露為一次停頓。

又稱
miss costmiss latency未命中懲罰