[譯]Intel, AMD及VIA CPU的微架構(39,完)
21. 微架構的比較
已經調查的最先進微架構代表了不同的微架構核心:AMD,Pentium 4(NetBurst),Pentium M與Intel Core 2核心。現在我將討論這些微架構的優缺點。我不討論記憶體頻寬的差別,因為這部分依賴於內部硬體及快取大小。這4個微架構型別都有不同快取大小的不同版本。因此,微架構的比較主要與CPU密集應用相關,與記憶體密集應用不那麼相關。
21.1. AMD K8與K10核心
這個AMD微架構比Intel處理器的微架構要簡單一些。這有一定的好處,因為處理器在複雜邏輯上消耗的資源更少。它也有次優亂序排程方面的缺點。通過一個全程3路的流水線,僅僅得到每時鐘週期3個巨集操作的吞吐率。從一個流水線移動巨集操作到另一個流水線的能力有限。
執行單元不如Intel處理器那麼特化。所有3個整數執行單元都可以處理幾乎所有整數操作,甚至包括最晦澀、少用的指令。只有整數乘法單元太昂貴,不能做到3個單元裡。這個通用性使得路徑簡單,代價是更大的執行單元。
3個浮點執行單元特化程度高些。僅最簡單的浮點被多個單元支援。巨集操作在3個浮點單元間的分派遠不算最優。這裡有一定的改進空間。
混用不同時延巨集操作,浮點執行單元還有問題。這個問題以一個相當複雜且低效的方式處理,通過阻塞一個短時延巨集操作的分派,如果能預測它將與之前一個更長時延巨集操作同時需要結果匯流排。一個更簡單、更有效的解決方案應該是將一個短時延巨集操作的結果儲存在流水線,直到結果匯流排可用。這可以解決,如果流水線被長時延巨集操作統治,短時延巨集操作將被長時間拖延的問題,而且它可以消除預測結果匯流排何時空閒的複雜邏輯。
所有執行單元有相當短的時延且完全流水線化,因此可以每時鐘週期接受一個新的巨集操作。
據說在同一時鐘週期裡9個執行單元(3個整數ALU,3個地址生成單元,3個浮點單元)可以執行9個巨集操作。但是,幾乎不可能通過實驗驗證這個宣告,因為回收階段被限制為每時鐘週期3個巨集操作。換而言之,AMD有大量的、永遠不會用完的執行資源。如果在回收階段的瓶頸被拓寬,那麼將有可能每時鐘週期執行更多的巨集操作。
AMD每條指令產生相當少的巨集操作。即使讀-修改與讀-修改-寫指令也僅產生一個僅在流水線的執行階段分解為微操作的巨集操作。這類似於PM與Core2設計裡的融合微操作。AMD K8設計沒有大於64位元(原文為byte)的執行單元,因此在AMD K8中,128位XMM指令產生兩個巨集操作。後續的AMD K10在浮點流水線中有128位單元,在一個巨集操作中處理向量指令。
AMD設計對一個巨集操作上的輸入依賴沒有嚴格限制。因此,像ADC EAX, EBX,CMOVBE EAX, EBX與MOV [EAX+EBX], ECX的指令都有一個巨集操作實現。在可比較的Intel處理器上,相同的指令必須分解為至少2個微操作,其中一個微操作不能有超過2個輸入依賴,包括條件標記。
在K10上指令獲取的吞吐率已經從每時鐘週期16位元組增加到32位元組。在被採用跳轉後,仍然有一個較低的吞吐率。2級快取的指令獲取特別慢。
指令解碼看起來相當高效。每時鐘週期可以解碼至少3條指令。
對總是去往相同方向的分支,分支預測良好,因為分支預測資訊同時儲存在1級快取與2級快取中。但預測規則分支模式的機制有比Intel處理器低的預測正確率。
快取系統每時鐘週期可以進行兩次記憶體讀,而Sandy Bridge之前的Intel處理器每時鐘週期僅能進行一次讀。
21.2. AMD Bulldozer,Piledriver與Steamroller核心
Bulldozer微架構是之前模型的一個重大的改進。
Bulldozer有2到8個計算單元,每個有兩個CPU核。程式碼快取,指令獲取器,分支預測,及浮點單元都在每個計算單元的兩個核間共享。在計算單元中僅使用一個核時,該設計允許每時鐘週期最多4條指令的吞吐率,在兩個核都使用時,每時鐘週期2條指令。
大多數執行單元是加倍的,使大多數指令可以每時鐘週期兩條的吞吐率執行。
浮點指令與整數向量指令的時延通常比Intel Sandy Bridge要長些。
對浮點操作的單執行緒吞吐率是每時鐘週期2個128位操作,這可以是加法、乘法或融合乘加。
AMD設計對一個μop上的輸入依賴數沒有嚴格限制。因此,像ADC EAX, EBX,CMOVBE EAX, EBX及MOV [EAX+EBX], ECX指令都以一個μop實現、在Intel處理器上,相同的指令必須分解為至少兩個μop,其中一個μop可以有不超過2個輸入依賴,包括條件標記,除了融合乘加指令。
指令解碼器每時鐘週期可以處理4條指令。Bulldozer與Piledriver每單元有一個解碼器,由兩個執行緒共享,而Steamroller每執行緒有一個解碼器。每時鐘週期4條指令的最大吞吐率最好通過混用整數指令與向量指令來獲得。
在Bulldozer中快取系統很差,Piledriver好些,Steamroller還要好些。
21.3. AMD Zen核心
在落後Intel幾年後,Ryzen處理器讓AMD重回競技場。Zen核心有每時鐘週期5條指令的吞吐率,是目前為止的記錄,128位向量程式碼的吞吐率特別高。Ryzen每時鐘週期可以計算4個128位浮點向量,或兩個256位向量。
在單執行緒應用中要充分利用提升的指令級並行,高吞吐率加重了程式設計師與編譯器的負擔。核吞吐率是如此高,每核執行兩個執行緒是合理的,不像其他某些核吞吐率較低的處理器,因為兩個執行緒競爭有限資源,可能會看到嚴重的效能下降。
新的μop快取是一個重要改進,它消除了在大多數關鍵迴圈裡指令獲取與解碼的瓶頸。
在所有層級大快取是一個特別重要的改進。但快取頻寬限制在每時鐘32位元組,比最好的Intel處理器要小。
21.4. Pentium 4核心
Intel Pentium 4(NetBurst)核心的設計片面強調時鐘頻率。導致就市場與聲譽而言,這個時鐘頻率確實有優勢,但就使高時鐘頻率可行的設計考慮而言,它有相當高的代價。需要長流水線,因為每流水線階段,電路做更少的工作。在P4微架構中,某些流水線步驟只是用來從晶片的一部分移動資料到另一部分。在高頻率下,物理距離變得重要。長流水線意味著高的誤預測懲罰。
每個執行單元保持儘可能小。不僅因為物理距離重要,而且因為散熱也是一個限制因素。越小的單元越特化,可以處理更少不同操作。這意味著除了最簡單的指令,其他指令都要求多個μop,某些指令還要求許多μop。
1級資料快取也相當小(8或16kb),但2級快取的訪問是快速的。
P4沒有像其他處理器那樣有程式碼快取,但有一個追蹤快取。追蹤快取以一半時鐘頻率執行,可能因為其大小。追蹤快取不儲存原始程式碼,而是已解碼μop。這些μop非常類似於RISC指令,因此核心可以使用RISC技術。在解碼是瓶頸時,在快取前將指令解碼為類似RISC的μop是合乎邏輯的。在某些其他處理器上解碼或預解碼是瓶頸的情形中,P4確實性能更好。
但追蹤快取沒有看起來那麼先進。例如,一條PUSH或POP指令在程式碼快取中僅需要1個位元組,但在P4E追蹤快取中需要16位元組。這意味著在相同面積的晶片上,能快取的程式碼更少。另外,在追蹤快取中,相同的程式碼可能出現在多個追蹤裡。在快取大小是受限物理因素時,導致快取裡程式碼更少。32位P4在追蹤快取中有一些資料壓縮,但這與使解碼簡單、高效背道而馳。在跳轉到程式碼其他部分時,把程式碼安排到追蹤快取消除了獲取時延,但在跳轉到另一個追蹤時,仍然有時延,而且因為追蹤快取以一半時鐘頻率執行,這個時延更高。是否將相同的程式碼儲存到多個追蹤是在消除跳轉與將更多程式碼放入追蹤快取之間權衡。
不管怎麼說,我嚴重懷疑追蹤快取使得設計更簡單。我不知道如何記錄追蹤、將實體地址對映到多個追蹤快取地址、確定是否跳轉到另一個追蹤或擴充套件一條分支指令上現有的追蹤,以及確定何時重排追蹤。對我而言,這像一個邏輯的噩夢。
指令解碼器每時鐘週期僅可以處理1條指令,而其他設計每時鐘週期可以解碼3條或更多的指令。顯然,解碼器有低優先順序,因為僅在從2級快取構建新追蹤時使用它。
P4有兩個執行埠用於ALU與其他計算(埠0與1),兩個額外埠用於記憶體操作與地址計算(埠2與3)。每個執行埠有1或多個執行單元。同時向兩個不同的執行單元分派兩個μop是不可能的,如果它們使用相同的執行埠。因此,這些埠是瓶頸。在埠0與1之間,執行單元沒有最優地分佈。所有浮點與SIMD(向量)操作,除了簡單的移動,去往埠1。這使得在浮點與SIMD程式碼中,埠1是一個嚴重的瓶頸。
兩個小整數ALU以2倍時鐘頻率執行。32位P4可以僅半個時鐘週期的虛擬時延進行錯開的加法。對條件標記的時延更長。64位P4E仍然使用雙倍速ALU,但時延是一個時鐘週期。對可由這兩個ALU處理的指令,吞吐率是每時鐘4個μop。雙倍速ALU特化來僅處理最常用的操作,比如在通用暫存器上的移動與加法。
其他執行單元有更長的時延,有時長得多。最諷刺的例子是在P4E上浮點暫存器到暫存器移動的7時鐘週期時延。在來自一個執行單元的結果作為另一個執行單元的輸入時,還有一個額外時鐘週期的時延。
一條128位XMM指令由一個μop處理,都能執行單元一次僅可以處理64個位元,因此吞吐率僅是每時鐘週期64位元。只有記憶體讀才有每時鐘週期128位的吞吐率。這使得對會使用128位操作的記憶體密集應用,P4/P4E是一個高效的微架構。
分支預測演算法尚可,但出於兩個原因,誤預測懲罰不同尋常地高。第一個原因顯然是長的流水線(20或更多步驟)。第二個原因是在誤預測分支裡的偽μop,在回收前沒有被丟棄。一個誤預測通常涉及45個μop、如果這些μop是除法或其他耗時的操作,那麼誤預測會代價極高。其他微架構一旦檢測到誤預測,可以儘快丟棄μop,使它們不再徒勞地使用執行資源。
相同的問題適用於未就緒寫轉發的記憶體運算元的假讀。P4將持續重演這個讀,連同依賴它的後續μop,直到記憶體運算元就緒。在一個寫後讀的記憶體依賴裡,這會浪費許多執行資源。這通常出現在引數在棧上傳送到一個例程時。在快取不命中與其他事件後,還存在μop的一個過量重演。在執行偽μop上浪費的資源數是如此高,它是一個嚴重的效能問題。
回收限制在每時鐘週期略少於3個μop。
21.5. Pentium M核心
PM是舊的Pentium Pro核心的一個改進,關注點是降低功耗。大量工作放在在執行單元與匯流排不使用時,關閉它們。更低的功耗有有利的一面。低功耗意味著可以增加時鐘頻率,而不會使晶片過熱。
指令解碼受4-1-1規則限制(第頁)。為了優化指令解碼,必須特別地按4-1-1規則調整軟體。不過,4-1-1模式被指令獲取邊界打破,對程式設計師或編譯器作者,這很難預測。這個問題將指令獲取速率降低到每時鐘週期小於16位元組,解碼速率降低到每時鐘週期少於3條指令(第頁)。在PM設計中,指令獲取與解碼絕對是弱的一環。
執行單元圍繞5個執行埠集中,以一個非常類似於P4的設計。埠0與1用於ALU與其他計算。執行單元在埠0與1間的分佈更加均勻,許多μop可以去往任一個埠。這使得保持兩個埠忙碌,比P4設計要容易。
使用2個執行埠都有的ALU,SIMD整數指令相當高效,時延僅1時鐘週期。浮點時延也相當低。
PM每指令產生的μop要少於P4。而這兩個設計都有每時鐘3個μop的吞吐率,PM每時鐘週期執行的指令更多,因為較低的μop數。低的μop數部分由於μop融合(第頁),以及棧指標的一個專用加法器(第頁)。不過,μop融合機制不能作用於XMM暫存器。這使得PM對MMX暫存器及浮點暫存器比XMM暫存器更有效率。
PM有每時鐘週期從永久暫存器檔案3個暫存器讀的限制。這很可能是一個瓶頸。
PM有一個先進的預測機制。迴圈計數器是我們已經期盼多年的東西。但這不足以補償非常小的、可能只有128項的分支目標緩衝。改進的預測間接跳轉的能力可能是減小BTB大小的必要條件。
PM不支援64位指令集。
回收階段的吞吐率與P4完全相同。雖然這兩個設計都限制在每時鐘週期3個μop,PM有更少的每指令μop,以及在執行單元更短的時延。這使得PM如此高效,可能比P4更快地執行CPU密集程式碼,雖然後者的時鐘頻率高50%。
21.6. Intel Core 2與Nehalem微架構
這個設計吸取了PM成功的哲學,更進一步地關注低功耗。低功耗使增加時鐘頻率成為可能。
擴充套件流水線與執行單元,以允許每時鐘週期4個μop的吞吐率。通過每指令釋出更少的μop,將資料匯流排與執行單元擴充套件到128位,這個吞吐率被進一步增加。快取與記憶體頻寬也被提升了。
Core2頁Nehalem有如此多的執行單元與執行埠,因此執行階段很少成為瓶頸。大多數執行單元與內部資料匯流排被擴充套件到128位,不像Intel與AMD之前的x86處理器,它們僅有64位執行單元。
不過,在設計中幾個弱點仍然存在。我準備在這個設計中指出3個與流水線餘下部分效能不匹配的部分,這些弱點很可能是瓶頸:
- 指令預解碼。指令獲取與預解碼機制已經改進,但頻寬仍然限制為每時鐘週期16位元組。在CPU密集程式碼裡,這很可能成為瓶頸。
- 暫存器讀埠。這個設計每時鐘週期可從永久暫存器檔案讀不超過2或3個暫存器。在許多情形裡,這可能是不夠的。
- 分支歷史模式表。分支歷史模式表太小了,它可能連累原本相當先進的分支預測機制。
- 讀埠。Core2每時鐘週期可以讀一個記憶體運算元,而AMD處理器可以讀兩個。讀埠不總能匹配執行單元的高吞吐率。
21.7. Intel Sandy Bridge及更新的微架構
這個新設計是一個重大改進。在Sandy Bridge裡處理了之前設計的許多瓶頸。
在Intel設計中,多年來指令獲取與預解碼都是一個嚴重的瓶頸。在NetBurst微架構中,嘗試通過快取已解碼μop來解決這個問題,不太成功。在Sandy Bridge設計中,在解碼前後快取指令。因此,μop快取有限的大小不那麼成問題,μop快取看起來非常高效。
自舊的Pentium Pro起,有限的暫存器讀埠就是一個嚴重且通常被忽視的瓶頸。在Sandy Bridge中這個瓶頸最終被消除。
之前的Intel處理器僅有一個記憶體讀埠,而AMD處理器有兩個。在許多數學應用中,這是一個瓶頸。Sandy Bridge有兩個讀埠,因而消除了這個瓶頸。
分支預測通過更大的緩衝與更短的誤預測懲罰得到改進,但沒有迴圈預測器,且誤預測仍然相當常見。
AVX指令集是一個重要的改進。在使用新的256位YMM暫存器時,浮點加法與乘法的吞吐率加倍。對降低暫存器壓力以及避免暫存器移動指令,新的非破壞性3運算元指令相當便利。不過,對混用有與沒有VEX字首的向量指令,有一個嚴重的效能懲罰。如果遵守程式設計指引,這個懲罰很容易避免,但不經意地混用VEX與非VEX指令是一個常見的程式設計錯誤,而且這樣的錯誤很難檢測。
一旦從一個系統消除最窄的瓶頸,第二窄的瓶頸將成為限制因素。在Sandy Bridge中要求關注的新瓶頸有以下這些:
- μop快取。這個快取理想地可以儲存最多1536個μop。在大多數情形裡,實際使用率遠低於此。程式設計師應該注意確保最關鍵的內層迴圈能放入μop快取。
- 指令獲取與解碼。自之前多個處理器以來,獲取/解碼速率都沒改進,對不能放入μop快取的程式碼,仍然是一個潛在的瓶頸。
- 資料快取庫衝突。增加的記憶體讀頻寬意味著快取衝突的頻率將增加。在最大限度使用記憶體埠的程式中,快取庫衝突幾乎不可避免。在Haswell處理器中,這個問題已經被解決了。
- 分支預測。雖然分支歷史緩衝與分支目標緩衝可能比之前的設計大,誤預測仍然相當常見。
- 執行緒間的資源共享。在併發多執行緒(超執行緒)開啟時,許多關鍵資源在一個核的兩個執行緒間共享。在多個執行緒依賴相同的執行資源時,關閉併發多執行緒可能是明智的。
22. 低功耗微架構的比較
Intel Atom,VIA Nano,以及AMD Bobcat都是為低功耗設計的小處理器。這些處理器有比更高功耗處理器低的效能,但對普通的辦公應用、嵌入式應用,甚至低流量伺服器足夠了。低價錢與低功耗使這些處理器,對要求不那麼高的應用,是一個好的選擇。
22.1. Intel Atom微架構
Intel Atom是比Core效能低的、小的低功耗處理器。它沒有亂序執行能力,僅在某些相當嚴格的條件下,可以併發執行兩條指令,就像15年前的第一代Pentium處理器。不過,內部設計與Pentium很不一樣。
Atom設計的主要缺點是順序執行與相對低的指令獲取速率。
併發多執行緒支援用處有限,因為兩個執行緒間共享的資源相當少,甚至對單執行緒使用也不足夠。某些版本有每個能執行兩個執行緒的兩個核。
22.2. VIA Nano微架構
VIA Nano是一個面向與Intel Atom相同型別應用的低功耗小處理器。Nano有一個相當先進的亂序流水線與強大的執行單元。在某些方面,執行單元的效能類似於Intel與AMD大得多的桌面處理器。浮點效能特別好。
對記憶體訪問與跳轉,Nano的時延比桌面處理器長,但整數與浮點計算的時延非常低。對單執行緒應用,總體效能顯著好於Atom。有兩個或更多獨立核的版本在多執行緒環境中提供了良好的效能。
22.3. AMD Bobcat微架構
AMD Bobcat有一個高效能且沒有明顯瓶頸的高效亂序流水線。執行單元僅是64位,對向量指令提供了較低的吞吐率。Bobcat有兩個獨立的核,在多執行緒環境中提供了良好的效能。
22.4. 結論
AMD、P4與Intel Core設計都可以每時鐘最多3個μop的最大吞吐率亂序執行指令。Core2,、Nehalem與Sandy Bridge每時鐘可執行4個μop。在高度混用整數與向量指令時,AMD Bulldozer與更新的設計每時鐘可以執行4個μop。
NetBurst(Pentium 4)設計有更高的時鐘頻率,意味著每時鐘更多μop。但在NetBurst上,每條指令產生比其他處理器更多的μop,意味著每時鐘更少的指令。高時鐘頻率的進一步劣勢是長流水線,因而高的分支誤預測懲罰。NetBurst微架構有如此多固有的效能問題,它沒有繼續下去。
PM、Core與AMD設計都使用較低時鐘頻率但每指令更少μop的相反策略。這個策略看起來對CPU密集應用提供了最好的效能。對許多指令,NetBurst有比其他處理器長的時延。這使得對有長依賴鏈的程式碼,它處於劣勢。
所有這些設計都有一個類RISC的、工作在簡單μop而不是複雜指令的執行核心。NetBurst與Sandy Bridge設計通過快取μop而不是指令,將RISC哲學推得更遠,NetBurst設計無法使人信服,因為它降低了每快取面積的資訊量,且追蹤快取的管理相比一個CISC解碼器,沒有節約時間。Sandy Bridge使用在解碼前後快取指令的折衷方案。結果看起來相當成功。
AMD使用在程式碼快取中標記指令邊界的不同策略,藉以消除了指令長度解碼的瓶頸。Intel在Pentium MMX中做了相同的事情,我不理解為什麼他們遺漏了這個策略。在Intel處理器中,指令長度解碼繼續成為一個嚴重的瓶頸。這個問題通過快取已解碼指令得到緩解,但NetBurst追蹤快取的容量與Sandy Bridge的μop快取仍然受限,因為μop比CISC指令更佔快取空間。
多年來,RISC哲學被視為通向高效能的最佳之路。Intel Core微架構以及AMD設計展示了偏離RISC、迴歸CISC原則的一個新趨勢。P4的類RISC設計帶有非常長的流水線與長的哲學時延,沒有說服力,並且追蹤快取看起來效率低下。迴歸CISC設計的好處有3重:
- 緊湊的CISC程式碼更好地支援有限的程式碼快取區域。
- 每指令更少的μop支援流水線更高的頻寬。
- 每指令更少的μop支援更低的功耗。
CISC設計的主要缺點是,指令解碼成為一個瓶頸。因為在程式碼快取中儲存指令邊界的技術,AMD處理器有比Intel設計更高的解碼頻寬。Intel設計仍然被限制為每時鐘週期16位元組程式碼,在許多情形下這是不夠的。
一開始的RISC哲學要求所有指令應該有相同的時延,以提供一個平滑的流水線。不過,這個原則很快被證明站不住腳,因為乘法、除法以及浮點加法比整數加法需要更多時間。在Intel微架構中,這個問題通過把不同時延的微操作傳送到不同執行埠得到部分解決(參考第頁表8.1)。
在Intel Core及更新的設計中對節能特性的日益關注,使得使用一個相對高時鐘頻率成為可能,儘管是一個每流水線階段要完成比NetBurst更多工作的設計。
AMD也使用一個每時鐘週期幾個μop的CISC設計。早期版本保持儘可能簡單,以降低必要的邏輯開銷。不過,這降低了亂序能力,以及執行單元的優化使用。
Intel Core與AMD K10處理器有完全128位的執行單元。更早的處理器在計算一個128結果時,使用一個64位單元兩次。因此,在這些處理器中不可能完全利用128位XMM指令。Sandy Bridge有完整的256位執行單元,除了記憶體讀與寫操作。我們將很可能看到AMD的處理器或支援AVX的VIA使用128位單元兩次來計算一個256位向量結果。在未來把向量大小擴充套件到512位或更大時,可能會發生相同的事情。
在AMD、P4與PM中每時鐘週期3個μop的吞吐率,在Core2與更新的設計中,提升到4個μop,但我不預期這個數字在將來會提升得很多,因為更高吞吐率的優勢沒有被完全利用,除非程式碼內在有高度的併發性。
相反,潮流是多執行核。不過,在單使用者系統中,我們需要多執行緒程式來充分利用多核。不能分解為多個執行緒的計算不能很好利用多核或多處理器。
許多微處理器有多個核。在NetBurst中引入了一個併發多執行緒技術(超執行緒)中間解決方案,並在Nehalem與Sandy Bridge中再次引入。微處理器有兩個共享同一個執行核的邏輯執行緒。如果兩個執行緒競爭相同的資源,這樣的好處有限,但如果效能受限於別的其他,比如記憶體訪問,併發多執行緒會有相當的優勢。某些處理器在這兩個執行緒間共享所有的資源,而其他處理器僅共享部分資源。這使得確定執行一個特定微處理器上的特定程式,併發多執行緒是否有好處,對程式設計師而言相當複雜。32位架構到64位的擴充套件已經是一個合乎邏輯且必要的事情。Intel走在AMD前面,帶著先進的Itanium RISC架構,但它缺乏市場要求的前向相容。AMD加倍了暫存器數的64位架構,仍然維持前向相容,已經被證明是一個Intel不得不效仿的商業成功。今天,所有x86處理器都支援x64指令集。
下面的表22.1比較了這3個設計上各種操作的執行時延。一個比較快取大小的表在手冊4“指令表”裡提供。
典型執行時延 |
AMD |
P4E |
Core2 45 nm |
Sandy Bridge |
整數加法 |
1 |
1 |
1 |
1 |
整數乘法 |
3 |
10 |
3 |
3 |
整數除法, 32 位 |
40 |
79 |
23 |
28 |
封裝整數移動 |
2 |
7 |
1 |
1 |
封裝整數加法 |
2 |
2 |
1 |
1 |
封裝整數乘法 |
3 |
8 |
3 |
3 |
浮點移動 |
2 |
7 |
1-3 |
1 |
浮點加法 |
4 |
6 |
3 |
3 |
浮點除法,雙精度 |
20 |
45 |
21 |
22 |
浮點向量加法 |
4 |
5 |
3 |
3 |
浮點向量乘法 |
4 |
7 |
5 |
5 |
表22.1. 指令時延的比較
23. 未來的趨勢
NetBurst設計中的高時鐘頻率被證明在功耗與晶片發熱方面代價過高。這導致了注意力從吉赫茲競賽轉向。自此,對功效的關注持續增加,在未來這個因素不會減弱,因為小型的電池供電計算機變得非常流行。
執行單元的速度與計算能力比記憶體訪問速度增加得更快。因此,可以預期在未來,在提升快取與記憶體頻寬上有強烈的關注。3級快取與更寬的資料通路將普及。
在現今微處理器上,因為長的流水線,分支誤預測代價很高。我們將很可能看到更先進的多級分支預測演算法,更大的分支目標緩衝與歷史表,多個分支併發的解碼與推測執行,以及在未來處理器中減少誤預測代價的斷言指令。我們還沒看到為降低誤預測懲罰大幅縮短的流水線。
在許多CISC計算機中,指令長度解碼是一個瓶頸。前向相容的要求阻止了向RISC指令的遷移。雙指令集計算機是一個可能的解決方案,但相當貴。快取已解碼μop在Intel NetBurst架構上不是一個很成功的解決方案,但在Intel的Sandy Bridge及其後繼者中要更成功一些。μop快取的一個劣勢是,相比傳統的程式碼快取,它需要多得多的每指令模面大小(die space)。更關注改進指令長度解碼器可能是一個更有效的解決方案。AVX與更新的指令使用新的、包括指令長度資訊的VEX編碼方案。這開啟瞭解碼器對有VEX編碼的指令,比最複雜的非VEX編碼指令,有更高吞吐率的折衷方案可能性。
快取μop的另一個方案是在指令快取中標記指令邊界。這解放了指令長度解碼的關鍵瓶頸。大多數AMD處理器使用這個方法,它也在Intel Pentium MMX處理器中。
由於這兩家公司間的一個專利共享協議,在Intel與AMD微架構間有一個顯著的匯聚。AMD拷貝了Intel的棧引擎與預測間接分支的機制。我們也可以預期某天Intel能與AMD 32位元組指令獲取速度一較高下。
不幸的是,指令集擴充套件不總是匯聚的。Intel的SSE4.1及SSE4.1指令集與AMD的SSE4.A及XOP(以前稱為SSE5)差異極大,這兩組指令集間的交集相當小。Intel從未拷貝現在過時的AMD的3DNow指令集,但他們從AMD拷貝了成功的x64擴充套件,以及其他幾條指令。傳統上,AMD拷貝所有Intel指令,但有時落後幾年。還好,AMD修改了他們提出的SSE5指令集,使其能與AVX編碼方案匹敵(正如我之前辯論的,這樣做是明智的)。現在AMD Bulldozer支援Intel的AVX指令集,包括256位YMM向量暫存器。不相容的融合乘加指令是一個可悲的故事,就像在我部落格裡討論那樣。幸好,Intel的Haswell與AMD的Piledriver現在都支援FMA3指令。
遷移到3及4個運算元指令對AMD比Intel更容易,因為對許多世代,Intel微架構不允許一個μop有超過兩個輸入依賴,而AMD從來沒有這樣的限制。在Haswell中,融合乘加(FMA)指令部分打破了輸入依賴的限制。
在CPU流水線中併發程度將不會增長太多,超過每時鐘週期4個μop,因為軟體中的依賴鏈可能阻止進一步併發。事實上,我們正看到不斷增加的核心數。現在即使低功耗處理器也有多個核心。這對製作多執行緒應用的軟體開發者提出了很高的要求。Intel與AMD都在做混合的解決方案,其中一些或所有執行單元在兩個處理器核間共享(Intel術語中的超執行緒)。
更低的指令時延是達到更高效能的一個方式,我們僅在低功耗處理器中看到。AMD的Bulldozer是第一個將暫存器到暫存器移動翻譯為零時延暫存器重新命名的處理器,不過Intel很快就跟上了。減少時延的另一個方式是指令融合。
減小時延的另一個方式是指令融合。我們將很可能看到乘法與加法指令的一個自動融合,以及其他常見指令的合併。寫到讀轉發機制也可能被改進以減小時延。
128位XMM暫存器到256位(YMM)的擴充套件,在2011年1月在Intel Sandy Bridge處理器中,隨後在同一年在AMD的Bulldozer中實現。下一步到512位的擴充套件已經宣佈,到1024位的稍後的擴充套件也被期待。顯然,沒有超過1024位向量暫存器的計劃。XSAVE與XRESOR指令是為未來這些擴充套件準備的。
有兩個版本的指令集用於512位向量。Intel MIC/Xeon Phi協處理器使用稱為MVEX的4位元組新字首來增加向量大小,把向量暫存器數加倍到32,並允許指令使用額外的屬性,比如掩蔽操作、型別轉換、廣播、組合、快取逐出提示、取整模式以及異常抑制。即將來臨的AVX-512指令集使用一個幾乎完全相同的稱為EVEX的字首。EVEX字首不允許型別轉換與組合,但包括了說明向量大小的位元。MVEX與VEVX指令集彼此不相容。它們在字首有一個位元不同,即使對完全相同的指令。MVEX與EVEX指令集都與之前的指令集前向相容。我預期帶有EVEX字首的AVX-512指令集將是未來處理器的標準,而MVEX將可能難以為繼。
很奇怪,MIC/Xeon Phi處理器也支援舊的、看起來過時的x86浮點指令。看起來在可預見的未來,我們無法完全摒棄x87指令,儘管在硬體中實現它們代價很高。
現在x86指令集有遠超1000條邏輯上不同的指令,包括用於文字處理、圖形、加解密、CRC校驗以及複數的專有指令。每個新處理器世代可能會擴充指令集,至少出於市場的原因。我們可能會看到更多應用特定的指令,比如用於加密目的的Galois域代數向量指令。
不過,從技術角度而言,持續增長的指令數可能不是最優的,因為它增加了執行單元的模面大小,因而限制了時鐘頻率。一個更可行的方案可能是使用者可定義指令。我們已經看過結合了專用微處理器核與可程式設計邏輯的FPGA晶片。在PC處理器上也可以實現一個類似的技術。這樣一個處理器將有類似於FPGA的邏輯陣列,可以一個硬體定義語言程式設計來實現應用特定的微處理器指令。除了程式碼快取與資料快取,每個處理器核將有一個用於硬體定義語言的快取。當然任務切換的代價將增加,但在核數目增加時,減少任務切換數更容易。
根據摩爾定律,持續遞增CPU速度的趨勢,在功耗、尺寸與價格方面存在缺點。現在我們看到另一個更小、低功耗處理器,由Intel Atom、VIANano及AMD Bobcat與Jaguar為代表的趨勢。這些輕量級處理器與數年前的桌面處理器一樣快,但更小、更便宜且功耗低得多。我們將看到這些小處理器在許多之前支付超出所需CPU能力的應用中替換大的高功耗處理器。
24. 文獻
當前手冊是可從 www.agner.org/optimize獲取的一系列5 本手冊中的第三本,如在第 頁介紹中提到的。
其他關於微架構的相關文獻:
- Intel 64 and IA-32 Architectures Optimization Reference Manual.
- Software Optimization Guide for AMD64 Processors.
- J. L. Hennessy and D. A. Patterson: Computer Architecture: A Quantitative Approach, 3'rd ed. 2002.
- www.xbitlabs.com
- www.arstechnica.com
- www.realworldtech.com
- www.aceshardware.com
- www.digit-life.com