CPU Wiki: Sandy Bridge Microarchitecture 前端(上)

在這裏插入圖片描述
Sandy Bridge 可以看做是自從NetBurst和P6之後的一個全新microarchitecture。Sandy Bridge回溯了最去的drawing board階段,從P6和NetBurst引入了很多有益的結構。儘管NetBurst是一個有嚴重瑕疵的結構,但是它引入了一些重要的創新,這些在Sandy Bridge中被重新實現並增強。它與一直到Nehamlem基本都沒有引入P4,P6的結構的早期Core結構不同。 Sandy Bridge引入並增強了前輩們的優點。
在這裏插入圖片描述

PipeLine
SandyBridge 專注於挖掘性能,降低功耗。Intel將降低功耗和提升性能作爲重點,達到了非線性的performance-to-power的提高。這些增強在frond-end和back-end中都可以看到。


Frond-end
前端的挑戰主要是從memory中讀取複雜的X86指令,解碼,並且將它們傳遞到執行單元,換而言之,前端需要能夠持續的將足夠的uOps發送到instruction code stream中,以保證後端能夠忙起來。當後端沒有被充分利用的時候,core是無法發揮他的全部性能的。弱的或者是沒有發揮全部能力的前端將會嚴重影響後端,最終導致糟糕的性能。在Sandy Bridge的case中,這個挑戰被重定向的分支和X86指令自身的複雜本性進一步複雜化。

Fetch & pre-decoding
到達core的內存塊,要麼來自cache,要麼是通過ring從其他cache 搬來,在一些偶爾的情況下,也會從主存中搬來。首先,指令需要從L2Cache取出,存入L1cache。L1cache是32KB,8 way 組相連。指令cache的大小與Nehalem相同,但是組相連數擴展到8-way。Sandy Bridge 使用過16byte的取數據窗口取指。這個窗口的大小好幾代都沒有變過。每個週期最多取16byte。要注意,取指是在兩個線程中公平的切換。所以每個線程都可以在另一個週期取指。這時他們還是marco-ops(X86變長指令)。指令被存入pre-decode buffer用於最初的準備工作。


X86指令是複雜的,變長的,是變長編碼並且可以包括不同的操作。在pre-decode buffer中,指令的邊界被檢測並標記到。這一一項相當困難的工作,因爲每條指令的長度都可以從1byte變化到15byte。甚至決定一個一條指令的長度需要檢測指令的好幾個byte。除了邊界檢測,指令前綴也被解碼,而且要檢測一些特性,比如分支。和之前的微架構一樣,預解碼器有着6 macro-ops的吞吐量,直到16byte被完全消化。需要注意的是,預解碼器不會沒消化完16byte就去取新的16byte block。比如,如果加載了一個新的數據塊,產生了7條指令。第一個週期,6條指令被處理,第二個週期一整個週期會浪費在剩下的1條執行上。這樣吞吐量就會是小於預期的3.5。如果是5條指令,前四條1byte,那麼第一個週期處理4條指令,第二個週期只能處理一條指令,吞吐量2.5。需要注意還存在特殊的情況Length-changing prefix(LCPs)會導致額外的預解碼損耗。真實的代碼通常低於4byte,而會產生好的結果。

在這裏插入圖片描述
Branch Predictor
取指操作和負責預測指令流向的分支預測單元(BPU)是同時工作的。所有的分支利用BPU預測其方向,包括return,非直接調用&跳轉,直接調用&跳轉,以及條件分支。與Intel 位架構的每一代處理器相同,分支預測也被提高了。分支預測器的一個提高會直接提高性能,降低功耗。由於深長的流水線,flush操作是相當昂貴的,會放棄in-flight的150條指令。在Nehalem中創造並引入Sandy Bridge的一個巨大的變化就是將frond-end 和 back-end的BPU相關進行解耦。在Nehalem之前,整條流水線都需要被徹底flush,然後前端才能重新操作。在Nehalem中這個被重新設計,前端可以在知道了正確的方向後就立刻開始譯碼,與此同時,後端仍然在flush預測錯誤的uOps。這可可以降低預測目標錯誤的代價。此外,Sandy Bridge中的分支預測器也被徹底重新設計了。分支預測期引入了Nehalem中的一些機制:Indirect Target Array(ITA), branch target buffer(BTB), Loop Detector(LD) 和 renamed return stack buffer(RSB)。


對於近返回(near return),Sandy Bridge 有16 entry return stack buffer。 BTB是單獨的單級結構,保存了兩倍於Nehalem L1/2 BTB entry的數目。這個改變應該可以提高預測覆蓋率。有趣的是,在Nehalem之前的架構Core中,也是使用的單級結構。因爲對於大多數的分支對於每條分支不需要較多的bit,因此對於較大 displacements的分支,使用了一個單獨的table。Sandy Bridge 的 4096 目標的 BTB table,通過1024組4路組成。
全局歷史信息表在Sandy Bridge中沒有增大,但是通過移除不能提升預測正確率的歷史來提高了性能。此外,全局歷史信息表爲數據dependent behavior 保留了更長的歷史,並且存儲了更有效的歷史信息


Baidu Intel完全重新了一個分支預測單元(BPU),精確度更高,並在三個方面進行了創新。
第一,標準的BPU都是2-bit預測器,每個分支都使用相關可信度(強/弱)進行標記。Intel發現,這種雙模預測器所預測的分支幾乎都是強可信度的,因此SNB裏多個分支都使用一個可信度位,而不是每個分支對應一個可信度位,結果就是在分支歷史表中同樣的位可以對應更多分支,進而提高預測精確度。
第二,分支目標同樣做了翻新。之前的架構中分支目標的大小都是固定的,但是大多數目標都是相對近似的。SNB現在支持多個不同的分支目標大小,而不是一味擴大尋址能力、保存所有分支目標,因而浪費的空間更少,CPU能夠跟蹤更多目標、加快預測速度。
第三,提高分支預測器精度的傳統方法是使用更多的歷史位,但這隻對要求長指令的特定類型分支有效,SNB於是將分支按照長短不同歷史進行劃分,從而提高預測精度。

Instruction Queue & MOP-Fusion 預解碼過的指令會被髮送到Instruction Queue(IQ)。在Nehalem中,指令隊列增長到18 entry,被兩個線程共享。Sandy Bridge 增加了數目,每個線程20,總計40。

在這裏插入圖片描述
指令隊列的一個關鍵優化是macro-op fusion。在一些case中,Sandy Bridge 可以將兩條macro-ops 融合爲單獨的一條複雜op。如果檢測到指令流中test或者compare的後續跟隨着一條條件跳轉,那麼他們會被轉化成單獨的一條 compare&branch 指令。在Sandy Bridge中,Intel擴大了macro-op fusion能力的範圍。Macro-fusion 現在可以將比如ADD和SUB這樣的指令與JUMP融合。這意味着,更多的case是可以融合的。或許最重要的case是典型的counter後面跟隨着一個條件分支的循環。這些就可以被融合了。這些被噢鞥和的指令在整條流水線上一直保持着融合的狀態,在分支單元執行時,也是一整條被融合的指令,因此從每個位置上都節省了帶寬。不過每個週期只能完成一條這樣的fusion。

Decoding
每週期預解碼器可以發送4條(如果其中一條指令爲macro fusion則爲5條)指令給譯碼器。像取指單元一樣,譯碼器每週期也在線程之間切換。譯碼器讀取macro-ops 然後發送規整的定長的uOPs。Sandy Bridge的譯碼器或多或少基本和Nehalem一致。和他的前輩一樣,Sandy Bridge使用四個譯碼器。譯碼器是非對稱的。第一個譯碼器Decoder 0是一個複雜譯碼器,其他的是簡單譯碼器。簡單譯碼器可以翻譯發射單條fused-uOP的指令。然而,複雜譯碼器可以翻譯1~4條fused-uOP的指令。譯碼單元輸出指令的上限爲4uops。這意味着,如果複雜譯碼器想要輸出超過一條的指令,那麼就有一個簡單譯碼器不工作。

在這裏插入圖片描述
Sandy Bridge 引入了一組256-bit SIMD指令集叫做AVX。這項擴展將以前存在的16個128bit的XMM寄存器擴展到256-bit YMM 寄存器,用於浮點向量操作(注意Haswell進一步擴展到了整數操作 )。大部分的新的AVX指令被設計爲是簡單指令,可以被簡單譯碼器譯碼。

歡迎關注我的公衆號《處理器與AI芯片》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章