為什麼AMD在推土機之後自己跳入了高頻低能的坑?

高主頻、深流水、高分支失效代價,這個坑是當年Intel在奔四時代掉過的。AMD因此而獲得過一段時間的相對優勢,應當對這種問題有所警覺。那麼為啥從推土機開始,AMD自己卻跳進去了呢?


簡而言之,你把一個「模塊」看做一個核心,把FX8350這種看成是四核(或四核八線程)也就是1800X的一半核心線程的產品的話,其實似乎也沒那麼差呢

這是AIDA64中cpu queen的測試,棋盤皇后是一個很有名的排列可能性問題,即在國際象棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行、同一列或同一斜線上,問有多少種擺法,AIDA64將棋盤擴大到了10X10,使得可能性較原本的8X8棋盤更多,也就加大了解答難度,也是一種典型的分支預測測試方法,支持多線程,演算法本身需要大量If/else語句作為條件跳轉,需要處理不少諸如當第i行有皇后的情況下,i+1行哪個位置可以放置皇后,由於CPU已經進行多級流水線時代,if的結果是true還是false沒有出來之前,流水線就需要裝入接下來執行的指令,所以CPU需要提前預測,選擇一條分支,棋盤皇后演算法便是很典型的分支預測測試,如果我們把FX8350視為四核八線程產物,實際並沒有那麼差(8700K的一半),1800X是2個8350的成績再多18%

我更傾向於認為,AMD的表現差,不僅僅是模塊思路被無視的問題,而是本身計算能力也相當有限,簡而言之見下圖,

這是當代CPU的整數和浮點最大吞吐量的規模,推土機系列是以一模塊為單位來對比的,我們看出zen的一個核心的計算能力就達到甚至超過了過去一個模塊的,過去AMD不僅輸在浮點上,整數也存在較大差距,比如SKL實現3發射256bit整數邏輯和加法,乘法也對推土機佔有較大優勢,即使不支持AVX的情況下,如cinebenchmark R15這樣的SSE2程序,支持128bit SIMD計算,那Intel在SSE的情況下也是執行3X128/核心的整數加法,邏輯運算,執行2X128/核心的整數乘法,在浮點上也能執行2X128/每核心的各類計算,這對於推土機及其後續產品來說,每一條都是用上一模塊都不見得能戰或勉強能戰的,哪怕是SSE的128bit程序,更何論遇上一些AVX2的256bit計算了,但是zen就不同了,如果都運行在SIMD位寬128bit的程序上時,其不會對Intel有規格上的劣勢,再加上IPC的確增加,目前benchmark絕大部分也是基於SSE指令集編譯的情況下,造就了zen的成功,關於AVX測試的情況可見我另外的回答

所以過去的AMD不能簡單說是高頻低能,高流水的說法不是很恰當,酷睿都還是14級流水線呢,通俗點說就是一個模塊兩個線程當一個核心用的思路沒有用成,而本身計算規模(不僅是浮點也包括整數)也不如Intel導致的,那為何不堆出Intel的計算規模縮小差距呢,這便是製程進步的魅力之一了


這個就要深挖推土機架構的設計思路了,AMD當時對市場的預判是,未來CPU的發展趨勢是多核心、重整數,浮點顯卡為王。

因此提出了模塊化概念,所謂模塊化,就是設計一個標準的模塊,包含若干個子核心,每個子核心都能獨立工作。通過擴展這種標準模塊可以輕易實現多核設計。

但是,理想是豐滿的,現實是骨感的,實際設計中發生了重大設計缺陷。

當時AMD對模塊的定位相當於過去的一個核心,而單獨的一個子核心則承擔一個線程的工作——可以把模塊視為一種物理多線程設計。相對於傳統的虛擬多線程大約25%的性能提升,物理多線程能發揮100%的多線程效率。然而,單個子核心的規模,只有傳統大核心的一半——相對應的,性能也幾乎只有一半。如果未來真的像AMD預測的那樣,多線程應用成為主流,單核性能不構成瓶頸,那麼推土機的設計堪稱完美,然而現實是殘酷的,單線程重度負載直到今天依然佔主流地位,所以,AMD這種孱弱的小核心設計,面對單線程負載,就只有傳統大核心一半的同頻IPC(別說對比酷睿,實際上對比自家的K10.5架構IPC也是倒退的)......自然是立刻撲街了,毫無還手之力……又為了彌補IPC的不足,推土機採用了長流水高主頻設計,通過儘可能拉高主頻的方式彌補先天缺陷,結果落下了高頻低能的帽子。實際上,低能是真,高頻只是補救的產物(順便感謝強悍的SOI工藝,不然就是低頻低能了)

Ryzen在設計之初,就針對這些固有缺點進行了針對性地改進,雖然還是模塊化,但是放棄了以前的模塊物理多線程概念,重拾傳統大核心,現在的模塊,只是一個標準設計的核心集合,每一個子核心,都有完整的規格,並通過SMT技術擴展多線程。所以Ryzen的單線程性能幾乎是一躍達到了和酷睿相當的水平(其實這才是AMD本應有的技術水平!)

當然,也有一些推土機首席架構師就是Intel奔騰架構設計師的說法,但這當然不是決定性因素……


先說結論:AMD對軟體應用發展的方向猜錯了,導致推土機推出的時候,面對流行應用的性能不但達不到預測中的性能,反而渣的一比。因此在新架構出來之前,只能靠提升頻率來提高性能。

詳細解釋如下:

技術背景:CPU是整台電腦中速度最快的部件,但是程序和數據都在存儲在成本最低速度最慢的外存(硬碟、U盤、光碟等)上,中間還有速度略慢,成本可以接受,但是無法長期存儲數據的內存。

CPU進行運算的時候,只能對CPU內部寄存器裡面的數據進行運算,因此需要先把指令和數據從外存上載入到內存中,然後再從內存讀取指令,把數據載入到CPU的寄存器,根據指令對寄存器裡面的數據進行運算。

這裡先忽略更慢的外存,只說到內存。因為內存速度比CPU速度慢,因此CPU經常需要等待內存中的指令和數據。在沒有任何輔助技術幫助的情況下,內存上的指令或者數據進入CPU大概需要幾十個時鐘周期。

為了縮短這個等待時間,現代CPU引入了很多技術:

  1. 多級緩存——一次性載入若干指令和數據。本來一個指令要等待幾十個周期,有了緩存,可以做到一批指令等待上百個周期。
  2. 指令流水線——前面的指令執行的時候,後面的指令已經進入管道等待執行,運算單元可以連續執行指令。
  3. 亂序執行——如果前面某個指令的執行需要等待數據,而且運算結果不影響後面指令的運算,後面的指令先進入流水線。
  4. 預測執行——對於存在分支的程序(例如IF 條件1,流程A,ELSE流程B)這種情況,條件許可的話,通過演算法猜測條件1的結果,根據猜測結果把流程A的指令載入流水線。當然,如果猜測錯了,那麼需要清空流水線,重新載入流程B的指令。又或者現有條件演算法無法預測,則只能等待條件1的計算結果出來再決定載入流程A還是載入流程B。
  5. 寄存器重命名——如果後面的指令和前面的指令使用同一個寄存器R1,但實際上前面指令的運算結果並不影響後面指令的運算,通過寄存器重命名的方法讓後面的指令使用R2,使得前面的指令把R1的結果寫入內存的時候就可以直接執行後面的指令而無需等待寫入指令完成。
  6. 指令級並行——增加運算單元,使得一個周期可以執行多個指令,例如推土機之前的K8/K10都有三個ALU,三個AGU。
  7. 集成內存控制器——減少等待內存數據的時鐘周期。K8是第一款這樣做的x86 CPU。

然而即使這樣,CPU也會有大量時間用在等待指令或者等待數據上,緩存會命中失敗,不是所有的指令都可以亂序,分支預測會不適用或者猜錯,有些指令就是必須等待前面指令對寄存器的運算結果。此外不是所有的應用都可以分成三個指令組來並行執行。結果就是CPU總有不少時間是部分運算單元甚至全部運算單元都是閑置的。

題外話,Intel的超線程技術解決的就是這個問題——單線程是沒辦法了,但多線程的時候,能把閑置的運算單元用上。當年的P4C,官方說法是增加5%的晶體管數量就可以獲得最多30%的多線程性能提升。到了今天,帶超線程的i7-8700K對比不帶超線程的i5-8600K,同頻率下單線程幾乎沒差,多線程性能可以提升到40%左右,極端情況可以提升將近60%。

背景介紹完了,再看看推土機。推土機應該是03年開始設計的,03年的PC市場是什麼情況?

  • K7和P3的頻率大戰剛結束兩年多,從99年到2000年一年時間,CPU頻率從K6-3D的400MHz提升到1G以上,之後的K7頻率一直提升到03年的2.2G。
  • 死對頭Intel的P4雖然效能低,但03年已經是第二代核心的P4C頻率從2.4G起跳,最高型號已經達到3.06G並且具備超線程,而且流水線深度沒有後來的Prescott那麼長,效能其實還可以接受,起碼大部分時候比K7強。
  • K8馬上發布,內部肯定已經知道K8就算頻率低點,憑藉集成內存控制器能把Intel的P4C乾的找不到北,而且兼容x86的64位是個很好的賣點,Intel的IA64可以直接無視。
  • 顯卡方面,3Dfx已死,nVIDIA的Geforce 5900和ATi的Radeon 9800正打的不可開交,顯卡的浮點運算性能讓兩家CPU廠商望塵莫及,用顯卡計算浮點的概念已經有人提出了。
  • 軟體方面,第一款支持多核心/單核心多線程的面向家用的操作系統——Windows XP 剛發布了兩年,02年打了SP1,才開始逐步普及並替代老舊的Win98,大量的軟體開發商還在一邊熟悉新的NT內核,一邊忙著解決自家產品和XP的兼容性問題。而XP本身是98/99年開始開發的,當時的主流硬體環境還是P2和低頻P3,所以XP對CPU的性能要求低得很——最低要求是奔騰233,推薦配置也不過300MHz以上。

這種情況下,CPU單核性能明顯過剩,多線程多任務很重要,浮點的未來是顯卡的觀念提出就很自然了。再加上當時P4的高頻率導致發熱嚴重的問題僅僅是有點苗頭,大家還都覺得隨著製程提升可以解決發熱問題。於是設計推土機的時候,更多的核心,更高的頻率,可以弱化單線程的整數性能,弱化整體浮點性能的設計目標提出就是水到渠成了。對比一下K10和推土機的架構圖:

K10架構圖

推土機架構圖

K10是單核心3ALU,3AGU,單線程的應用三個整數單元都可以用。推土機一個模塊兩個整數核心,每個核心只有2ALU+2AGU,單線程應用的話,整數性能只有K10的2/3(當然,還有其它方面的提升,實際單核心性能下降沒有這麼厲害)。實際評測中,同頻率下,4模塊8核心的推土機,單核干不過的K10,8核心也干不過6核心的K10。

然而理想是美好的,現實是骨感的……CPU的性能過剩,PC市場的迅速發展,互聯網的普及,軟體開發商大量出現,導致的結果就是程序員群體快速擴大和平均編程水平的降低。不是迫不得已,沒幾個開發商願意花時間精力成本去優化代碼性能,去使用更麻煩的多線程開發。另一方面顯卡計算直到07年發布的G80才真正出現,但因為其固有的局限性無法替代CPU的浮點運算單元,而且複雜的開發難度也讓很多應用開發商處於觀望狀態。

於是推土機每模塊雙整數核心單浮點核心的設計完全押寶錯誤:更小的整數核心導致單線程整數性能被削弱,又沒有多少整數應用是多線程的能夠利用上另一個整數核心;往往做了多線程優化的應用都是需要大量浮點運算的,於是變成兩個線程搶一個浮點核心,如果不限制線程數量以及執行核心反而會因為線程切換導致效率下降。

另外更深的流水線對分支預測、緩存命中和亂序執行的演算法正確率要求更高,偏偏這些都是AMD的弱項——從K8直到現在的Ryzen,提升內存性能(提升頻率或者降低延遲)都能大幅提升AMD CPU整體性能,而Intel CPU性能提升幅度很小的原因就在這裡——因為和Intel相比,AMD的CPU核心要直接訪問內存的頻率高的多。

找了個太平洋的推土機和同頻肥龍2的對比評測,看看推土機的性能有多爛:

整數性能,單核多核都不如6核心肥龍2

浮點也不行,依然單核多核全敗

另一個浮點,還是不行

當然,應用優化好了還是可以的,單核超越K10,多核更是輕鬆幹掉

如此低能,就算明知道高頻是坑也只能往下跳。自己挖的坑,流著淚也要自己填上。

正因為到05年,已經能看出推土機的設計押寶錯誤,AMD才會在K8風光之後,估計小改版的K10無法正面應對走回正路的酷睿2(酷睿2是06年才發布,但05年移動市場上的Dothan的性能表現已經足以預測這點),在06年不惜得罪之前緊密合作的nVIDIA,斥資54億美金收購ATi,期望能使用顯卡取代CPU的浮點運算——結果很明顯,10年過去了,至今為止支持顯卡加速的應用還是很少,而且其中大部分只支持顯卡市場上死對頭nVIDIA的CUDA,這是另外一個故事了。


如果CPU 架構別的地方 能有很大的進步, 就不會搞高流水線 高頻了。。。

話說推土機 18雞的 流水線其實還好吧。。我記得 P4 最勇猛的時候是32雞流水。。。喪心病狂


其實這事吧…是因為推土機ipc沒做好,才不得不轉去飈高頻,並不是AMD想去高頻高功耗的…屬於被逼無奈

推土機是想自己做個多線程的內核出來,又不想抄smt架構,所以自己搞了個共享fp/cache的mt架構,本來想法其實挺好…奈何實現碰到不少問題:比如第一代的時候,如果使能兩個線程,前段解碼速度直接減半…到後面終於解決這些問題的時候,性能和Intel當時的產品差距有點大,所以就沒下文了

另外推土機系列的末級緩存構架真的垃圾…不知道誰設計的


還是盲目堆多核的原因吧。這個畢竟是桌面cpu,在堆核的同時要兼顧單線程性能才行。比如sparc那種只面向伺服器市場的,更重視吞吐量,核相對就比較簡單,頻率高,線程多。

本身從農機系列core的規格來說,各種buffer的大小大致是nehalem的水平,但執行單元比nehalem更少,所以性能嘛,只能堆下頻率了。

流水線長度還好吧,20左右,現在zen和skylake大致也是這個長度,如果是從uop cache出的話可以少6,7個周期


推薦閱讀:

遊戲對ati顯卡和n卡的優化有差距嗎?
Intel 要出帶超線程的 i5 對抗 AMD Ryzen

TAG:中央處理器CPU | AMD | 中央處理器CPU計算機體系架構 |