程式設計師的 CPU 微架構

重排緩衝器(reorder buffer)

/ ROB -> robb /

一個亂序中央處理器以「輸入何時就緒」的順序執行指令,但它仍必須讓結果以原本的程式順序呈現,程式才會正確運作。它如何把混亂的執行與有序的結果調和起來?它維護一個佇列——重排緩衝器(ROB)——記住目前所有正在途中的指令,按程式順序排列,且只讓它們從佇列前端、依序地完成。

以下是它的生命週期。一條指令被解碼時,會在 ROB 尾端配到一個槽。接著它可能亂序執行,其結果被保留在它的 ROB 槽裡、而非寫進真正的架構狀態。緩衝器只從頭端、以嚴格程式順序退役指令:前端的一條指令,要等它自己已完成、且它之前的每一條都已退役後,才退役(把結果提交到架構暫存器與記憶體)。所以執行是亂序、提交卻是有序。ROB 也讓對例外與誤測的精確行為成為可能:若一條被推測執行的指令結果是錯的,它的 ROB 項目就在退役前直接丟棄,彷彿從未跑過。任一時刻坐在 ROB 裡的那組指令就是「途中指令(in-flight instructions)」,而 ROB 的大小(現代核心常為 200 到 600 多個項目)設定了指令視窗——核心能往前找多遠的獨立工作。

這個大小為何對你要緊:ROB 是「亂序執行能隱藏多少記憶體延遲」的字面上限。要在一次 300 週期的 DRAM 失誤期間跑有用的工作,核心需要足夠多的獨立指令在那條停滯載入後面、於 ROB 中等待;若緩衝器被「全都相依於那次載入」的指令塞滿,核心就停滯,因為它再也配不出新的槽。這正是「長相依鏈」與「許多同時發生的快取失誤」如此傷害效能的硬體原因——它們耗盡了視窗,亂序機制再也沒有東西可重疊。

若兩次獨立的 DRAM 載入能同時都在 ROB 中途中,它們各約 300 週期的延遲會重疊,總共約花 300 週期。但一個指標追逐迴圈 p = p->next,一次只能有一次載入在途中(每次都相依於上一次),所以 N 次失誤要花 N × 300 週期——ROB 幫不了一條序列鏈。

記憶體層級平行性活在 ROB 裡:獨立的失誤會重疊;相依的鏈則序列化。

重排緩衝器既讓亂序執行在可觀察上正確、又能從誤測中復原——它的有序退役也正是為何例外看起來精確、即使執行其實是被打亂的。

又称
ROBinstruction windowin-flight instructions重排序緩衝區