閱讀本文之前,請先參閱前情提要「為悼念Intel NetBurst的失敗而刻下的墓誌銘 (上)」。回歸正題,一般坊間媒體與電腦玩家,對Intel NetBurst微架構與Pentium 4家族處理器的刻板印象,不外乎「一昧追求時脈,忽略真實效能,造成過熱問題」,但假使事情真有這麼單純,Intel真的蠢到眼中只有時脈 (反觀同時期那時脈連1GHz都到不了的「儲君」Itanium),各位科科也不會看到這短期連載了。
打造高時脈處理器的關鍵
事實上,魔鬼藏在細節中,NetBurst是非常非常有看頭的酷玩意,有太多值得大書特書的驚人特色,否則某位前Intel院士也不必寫出厚達近1700頁的磚頭,以後大概也不會出現如此具有話題性和爭議性的處理器微架構了吧。真的要將NetBurst分析得很詳盡,恐怕沒個兩三萬字是搞不定的,也因此,筆者只挑比較核心的關鍵來談談。
首先,先回到原點,想打造一顆高時脈處理器,除了切深指令管線,縮短每個階段的延遲,還有哪些需要特別考慮的地方?
一般人對於同步化「管線 (Pipeline)」的傳統認知,不外乎將工作切割成幾個處理時間大致相同的階段 (Stage),每個階段中間塞入由時脈 (Clock) 控制的鎖存電路 (Latch) 或階段暫存器 (Stage Register),包含出入口,一個被分割成N個階段的組合邏輯電路 (Combinational Logic),就需要N+1個鎖存,每個階段一起運作。
在某個階段的工作尚未完成前,前一個階段不能送資料進來。管線所能執行的最高頻率,決定於延遲最長的階段。但同步化管線會遭遇晶片不同部位的時序有所偏差的時脈偏斜 (Clock Skew) 現象,鎖存電路與階段暫存器也會增加額外的延遲時間、電路面積與耗電量,不易設計線路結構更複雜的運算單元,並限制晶片的時脈與性能。
如果科科們還在這樣想,就落伍了,早在1969年,學術界就有高人提出「Wave Pipeline」的概念:打通整條管線的任督二脈,一個時脈內灌入兩組以上的資料,進入組合邏輯電路,使其像波浪般的自由流動,再藉由動態調整控制訊號延遲時間的緩衝器 (Adjustable Delay Buffer),使其不會前後相互干擾,處理器只要在「第幾波」可以在管線的出口「收割」運算結果即可,例如:加法器尚未輸出運算結果前,後面就偷偷塞進新的訊號。換言之,Wave Pipeline的理論最高時脈,決定於「最長與最短訊號延遲的差距」,堪稱某種程度的逆向思考全壘打。
雖然早在1960年代末期,Wave Pipeline就應用在開「非循序指令執行與預測執行」之先河的IBM 360/91大型主機的浮點運算器,但當電腦輔助晶片設計工具 (EDA Tool) 漸漸普及後,晶片設計者較能精確估算電路內每一個訊號的傳遞時間與位置,才讓Wave Pipeline慢慢流行,以便減少電晶體數量、縮小晶片面積、降低耗電量,並提高運作時脈。
根據已公開資訊,Pentium 4與Itanium 2是Intel首次採用Wave Pipeline的處理器,而後者更因此讓八階管線的Itanium 2,在相同180nm製程時,時脈遠超過十階管線的初代Itanium。
只需存放需要被執行的指令
其次,做深管線是一回事,有沒有辦法餵飽足夠的指令,那又是另一回事,況且當碰到分支指令,就需反覆進行「分支預測→擷取指令→解碼指令」這繁瑣的過程,計算記憶體有效位址、執行分支預測、TLB將虛擬位址轉換為實體位址、從快取或記憶體擷取可能位於不連續位址的指令、解碼指令,都會耗費時間,不利塞滿管線。為此實作龐大的複數指令解碼器,更會激增晶片成本,畢竟x86處理器除了控制單元,就是這裡特別的昂貴,也特別的耗電。
所以Intel釜底抽薪,旁徵博引當年被Fujitsu取消的SPARC64 V原始設計,將第一階指令快取改造成「依據分支預測機制而得知的程式碼執行順序,而排好排滿的的微指令 (uOp) 快取」,也就是熟悉Pentium 4的科科們,耳孰能詳的Execution Trace Cache,並只需存放需要被執行的指令。當然,Trace Cache也有內部的分支預測機制,這裡就不詳談了。
所謂的Trace,則意指「透過分支預測結果,而取得的基本程式區段 (Basic Block)」,無論這些指令如何散布於記憶體四處,但解碼後就一同循序的放在同一條Trace內,可大幅簡化指令讀取動作,讓被解碼後的微指令,源源不絕的灌入處理器的執行單元。NetBurst微架構的Trace Cache,每個時脈週期最多輸入三個微指令。坦白講,光看到這裡的份上,NetBurst的指令輸出率,實在說不上有多突出,也沒有比前代P6來得高明。
Trace Cache的明顯缺點
不過Trace Cache的缺點也很明顯。首先,假若發生分支預測錯誤,或所需要的指令並未在Trace Cache內,就必須重新啟動「標準」的指令擷取/解碼程序,再根據分支預測的結果,重新建立Trace,耗費大量時脈週期,也變相降低能耗效率。
其次,被解碼後的微指令,勢必比被編碼的指令長得多,也激增實際所需的SRAM容量。Pentium 4的Trace Cache的容量為12K (12288) 個微指令,命中率約等同於8kB到16kB的傳統第一階指令快取,但卻吃掉了高達80kB (180nm製程Willamette,有做資料壓縮) / 96kB (130nm製程Northwood) / 128kB (90nm製程Prescott) 的SRAM容量,在晶粒圖上非常的「搶眼」。
也難怪一直有人這樣認為:Intel用SRAM容量去「等價交換」所費不貲的複數指令解碼器。但問題來了,這是否真的「等價」嗎?以事後諸葛的角度來看,Intel最終仍逐步回到複數指令解碼器,並搭配小型化的微指令快取,設法降低啟動解碼器的機率,才是最有經濟效益又兼顧效能和功耗的手段。
不知不覺中,字數又破表了,那兩倍時脈整數運算兼位址計算單元、四倍時脈資料傳輸率系統匯流排、超執行緒、將執行完畢的回存直接載入執行單元 (Store-To-Load Forward) 的轉送機能、還有遭遇因缺乏運算元 (快取誤失、回存轉載入後發現記憶體位址誤判、無預期的暫存器相依和臨時無可用執行單元) 而引發微指令執行失敗的「重新啟動直到搞定 (Replay)」機制,都跑到哪裡去了?各位科科呀,你是第一天看這個專欄嗎? (下期待續)
4 則回應