前饋(forwarding)
假設一名職員算出一個小計,本該把它歸檔進活頁夾,而片刻後第二名職員需要那個小計。慢方法:第一名職員歸檔,第二名走到活頁夾把它讀回來。快方法:第一名職員在寫好的瞬間,直接把數字隔著桌子遞過去。前饋就是管線版的這種隔桌遞交——把剛算出的結果直接繞給需要它的指令,而不必讓它走過暫存器檔那條遠路。
回想那個資料危障:add x1, x2, x3 接著 sub x4, x1, x5。add 的結果 x1 在它 EX 階段結束時誕生,坐在 EX/MEM 管線暫存器裡,但要到兩週期後的 WB 才抵達暫存器檔——對 sub 太晚了,它下一週期就要在自己的 EX 用到 x1。前饋加上短短的線(配多工器來選擇它們),把值直接從 EX/MEM 暫存器繞回 ALU 輸入。一個小小的前饋單元盯著看是否相符——較早指令的目的暫存器是否等於較晚指令的來源暫存器?——若是,就把新值導上旁路。結果恰在 sub 需要時抵達,一個週期都不損失。
前饋是讓管線保持填滿最重要的單一花招,因為它把幾乎每個資料危障變成無事發生。生產者可從好幾個點前饋——EX/MEM 暫存器與 MEM/WB 暫存器都接到旁路——涵蓋相隔一兩條指令的相依。關鍵的誠實限制:前饋只能遞交已經存在的值。對載入而言,資料要到 MEM 階段之後才備妥,所以緊接的下一條指令的使用仍然來不及被前饋——那個載入-使用的情況恰好迫使一次停頓,是前饋獨力無法抹除的唯一危障。
add x1, x2, x3(在第 3 週期的 EX 算出 x1)接著 sub x4, x1, x5(在第 4 週期的 EX 需要 x1)。沒有前饋,sub 得停頓到第 5 週期的 WB。靠一條從 EX/MEM 暫存器到 ALU 輸入的線,x1 在第 4 週期恰好準時送達——零停頓。
前饋把結果從管線暫存器直接繞回 ALU,零損失週期地化解多數資料危障。
前饋無法變出尚未算出的值。載入的結果要到 MEM 之後才備妥,所以緊接載入之後的相依指令仍需一次停頓——載入-使用危障。前饋縮短那段延遲,卻無法完全移除它。