管線化與危障
管線清空(pipeline flush)
你猜導航會說「直走」,於是往前開——然後它說「左轉」。現在你在錯的路上做的一切都得撤銷,你從岔路重新開始。管線清空就是那個撤銷:當機器發現自己一直在處理錯的指令——最常是在分支誤測之後——它會在那些指令造成任何持久傷害之前,把它們從管線裡丟掉,並從正確的位址重新開始提取。
清空仰賴一個關鍵事實:那些錯路指令雖然被提取且部分處理了,卻還沒提交——它們還沒把結果寫進任何程式可觀察到的暫存器或記憶體。所以硬體可以安全地把它們轉成氣泡來取消:它們的控制訊號被強制設為「什麼都不做」,抹去它們本要做的寫入,而程式計數器被重導到正確的目標。錯的指令在管線裡走得越深,要清空的就越多——這正是為什麼深管線裡的誤測比淺管線裡的代價更高。
清空是推測的成本面。分支預測讓機器沿猜測的路徑往前衝,而且絕大多數時候是對的;但在罕見的猜錯時,清空丟掉所有推測性工作,管線必須從頭重新填滿,代價等於錯路走了多遠的週期數。這是每個推測性特性誠實的稅,也是為什麼較高的誤測率或較深的管線會直接抬高有效的每指令週期數。關鍵是,清空只花時間,永不損及正確性——被清空的指令消失得彷彿從未跑過。
預測器猜某分支不跳,提取了後面兩條指令;分支解出為跳。機器把那兩條轉成氣泡清空、把程式計數器重導到分支目標、重新提取——在這條短管線裡是兩個週期的誤測懲罰(在深管線裡多得多)。
誤測後,清空丟棄未提交的錯路指令並從正確目標重新提取——花的是週期,永不損及正確性。
清空之所以安全,正因為推測性指令尚未提交。這也是 Spectre 與 Meltdown 背後的安全皺褶:被清空的指令不留架構痕跡,但它們的微架構副作用(快取狀態)可能洩漏——一個效能特性變成攻擊面。
又称
另见