CPU到底是怎么工作的?你知道嗎?

對于同級別的CPU產(chǎn)品而言,AMD CPU的單核性能(甚至總體性能)比Intel CPU的差,甚至差距不小,這是不爭的事實。然而,幾乎沒有人問一句為什么如此,或者只是略知一二(包括我)。本文就用盡量淺顯的語言探討一下這個實際上極為復(fù)雜的問題。

鑒于Intel和AMD都沒有披露新品的whitepaper的習(xí)慣,所以我用信息比較充足的有點久遠(yuǎn)的型號進(jìn)行講解,就是Intel的Sandy Bridge/Ivy Bridge(第2、3代酷睿)和AMD的Bulldozer/Piledriver(推土機(jī)、打樁機(jī))微架構(gòu)。目前來講,兩家的微架構(gòu)設(shè)計都大體穩(wěn)定,從比較新的Broadwell和Steamroller的各方面信息來看,它們?nèi)匀换狙赜昧藦腟andy Bridge和Bulldozer以來的方案,沒有本質(zhì)的變化。

(因此農(nóng)企想要翻身,只能把希望寄托在遙不可及的Zen微架構(gòu)上了)

首先來說基礎(chǔ)知識,就是CPU是如何工作的。學(xué)習(xí)計算機(jī)科學(xué)的童鞋可能對下面的這些東西比較了解。

CPU之所以能完成這么多的事情,是因為它在時時都在執(zhí)行著很多的指令(instructions)。指令就是我們所運(yùn)行的操作系統(tǒng)和各種程序發(fā)送給CPU的命令,CPU根據(jù)這些指令來做出各種響應(yīng)。

CPU能夠執(zhí)行的所有指令的集合就叫做指令集(instruction set)。目前我們最常見的Intel和AMD CPU,其都采用最經(jīng)典的CISC x86指令集,以及在x86指令集上的某些擴(kuò)展,也就是說絕大部分是相同的。

另外,CPU中還有兩個重要的部件,分別為寄存器(register)和緩存(cache,為了方便簡寫為$),它們都擔(dān)負(fù)著暫存指令或者數(shù)據(jù)的作用。

寄存器處于CPU內(nèi)部,有很多組,是最高速的存儲單元,容量非常小。緩存可以處于CPU內(nèi)部或外部,其存儲速度比寄存器慢,但比內(nèi)存快得多,并且容量可以用KB或MB來衡量。另外,緩存可以分級,離CPU核心最近的叫做一級緩存(L1$),次近的叫做二級緩存(L2$),以此類推。

只有指令沒有用,必須還要有一套方法來驅(qū)動CPU做事情,否則不過是空殼而已。這套方法就叫做流水線(pipeline)。

這個概念并不抽象,大家可以把它想象成工廠裝配車間里的流水線:從一堆零部件開始,經(jīng)過流水線上十幾位工人的組裝,最后出來的時候就變成了一臺可以使用的設(shè)備。并且,工廠里肯定不只有一條流水線,可能有數(shù)十條,也就是上百甚至上千位工人同時工作,生產(chǎn)效率就會變得非常高。

從上世紀(jì)90年代的奔騰時代之前,CPU中就引入了流水線的概念。當(dāng)時的5段流水線模型十分經(jīng)典,其設(shè)計經(jīng)過逐代擴(kuò)充,目前仍然在用。這個經(jīng)典的模型就是:

取指(Instruction Fetch)→譯碼(Instruction Decode)→執(zhí)行(EXecute)→寫回(Write Back)

分別簡稱為IF、ID、EX和WB,其中ID階段有兩段,分別稱為ID1和ID2,所以一共5段。

顧名思義,這條流水線的邏輯就是:從緩存或者內(nèi)存中取得指令→對指令進(jìn)行翻譯,變成CPU能夠理解的具體功能→按照翻譯結(jié)果,執(zhí)行運(yùn)算動作→將運(yùn)算結(jié)果寫回存儲器中。很容易理解吧。

大家都知道,CPU的運(yùn)作是靠時鐘信號來驅(qū)動的,這個信號的頻率就叫CPU的主頻(main frequency),頻率的倒數(shù)當(dāng)然就是周期了。一般來講,每個流水線階段的執(zhí)行需要花費(fèi)1個時鐘周期(clock cycle,為了方便簡寫為CC)。

因此,如果這樣的流水線執(zhí)行4條指令,那么它的執(zhí)行時空圖就如下。

也就是說,采用這種流水線只需要8CC就可以執(zhí)行4條指令,效率非常高。到了奔騰時代之后,更出現(xiàn)了超標(biāo)量流水線(superscalar pipeline),也就是CPU中有多條流水線同時執(zhí)行指令,效率幾乎翻倍提高。另外,還出現(xiàn)了超流水線(super pipeline),也就是流水線的級數(shù)大大增加,規(guī)模明顯提升。分別的示意圖如下。

但是,這樣的流水線設(shè)計也存在問題,具體來講有二。

第一,考慮同一流水線中先后執(zhí)行的兩條指令1:add a,b和2:xor c,a,也就是說2需要1的計算結(jié)果,這種關(guān)系叫做相關(guān)性。當(dāng)指令2執(zhí)行到上表中第5個CC時,無法進(jìn)入EX階段,因為此時指令1的結(jié)果還未寫回寄存器,也就是說指令2的EX階段必須拖到第6個CC才可以執(zhí)行,浪費(fèi)了一個CC的時間,這叫做流水線的阻塞(stall)。超流水線級數(shù)越多,這種現(xiàn)象就越發(fā)明顯,效率就越低。如下圖。

第二,考慮超標(biāo)量流水線中,不同流水線中執(zhí)行的兩條指令。如果排在前面的指令執(zhí)行速度太慢(比如涉及耗時嚴(yán)重的訪存操作),那么會造成后面早已執(zhí)行完畢的指令不得不等待,造成更嚴(yán)重的性能問題。

也就是說,基于線性通路的流水線,對于目前的復(fù)雜的微處理器而言是并不適用的。因此,Intel早早就提出了“亂序執(zhí)行”(out-of-order execution, OOO EX)的概念,采用非完全線性的通路來規(guī)避這個問題。也就是這樣的。

我借助這個圖粗略講一下現(xiàn)代處理器的執(zhí)行過程。

上圖是一個四發(fā)射、亂序執(zhí)行的流水線框圖,從1995年以來的Intel處理器基本都采用類似的設(shè)計方案。所謂多發(fā)射(multiple issue),就是處理器能夠同時獲取并譯碼多條指令,目前的處理器幾乎都是四發(fā)射設(shè)計。

首先,在取指過程中,會多出一個分支預(yù)測(branch prediction, BP)的階段,圖中未明確示出。分支預(yù)測器能檢測諸如跳轉(zhuǎn)、返回等動作的大致發(fā)生時機(jī),并提前把跳轉(zhuǎn)目的地的指令加載到指令緩存(I$)中,以提高效率。

然后,經(jīng)過多個譯碼器的譯碼,指令被分解成為上文所述的CPU能夠理解的操作,這些叫做微操作(μop)。微操作被送入寄存器別名表(RAT),進(jìn)行重命名,以防止多條指令共用一個對程序猿非透明的寄存器時產(chǎn)生的相關(guān)性,簡單來講,就是用內(nèi)部的臨時寄存器來替代一般我們能見到的寄存器來進(jìn)行操作。重命名完畢后,微操作進(jìn)入后面的重排序緩存(ROB)中,進(jìn)行重新排列。

然后就是亂序執(zhí)行的重點了。微操作從保留站(reservation station, RS)中,分別打入不同的執(zhí)行端口(port),同時執(zhí)行。每個端口都是全速運(yùn)行的,只要微操作準(zhǔn)備就緒,并且有空閑的對應(yīng)端口,那么它就可以立即被執(zhí)行,而不用關(guān)心其他微操作的執(zhí)行狀態(tài),也就是可以跳過任何還沒有準(zhǔn)備就緒的微操作。這樣,流水線產(chǎn)生阻塞的可能性就大大地降低了。每個port都可以負(fù)責(zé)一種或多種事務(wù),如整數(shù)運(yùn)算、浮點運(yùn)算、存數(shù)據(jù)、取地址等。

當(dāng)一條指令分解成的所有微操作被執(zhí)行完畢之后,它們會返回保留站,并通知各自的地址,通過地址可以將微操作重新聚合為一條完整的指令。完成的指令排成一個隊列,并退出流水線。也就是說,盡管所有指令的碎片是亂序執(zhí)行的,但從流水線中出來時,它們?nèi)匀皇琼樞虻模透匀欢坏囊粯印?/p>

基礎(chǔ)知識講完了,下面開始對比,看看農(nóng)企為何不太給力。這方面的內(nèi)容非常多而且繁雜,我會打一些草稿,因此本帖更新會持續(xù)到明天,請大家見諒。

為了描述方便,后面用SNB/IVB代表Sandy Bridge/Ivy Bridge,BDZ/PDV代表Bulldozer/Piledriver。

首先看SNB和BDZ的簡單框圖。下面的是以i7 2600為例。

下面的則是以八核心Opteron為例,畢竟圖上寫了個Interlagos Node,反正是推土機(jī)就好了,你們可以把它當(dāng)成FX-8150之類的。

我們都知道,Intel的CPU采用超線程(hyper threading, HT)技術(shù),使得一個物理核心對高層而言看起來像是兩個核心一樣,這種邏輯的、虛擬的核心在Intel的概念內(nèi)叫做線程。而AMD的CPU采用模塊化設(shè)計,就是每兩個物理核心集合為一個模塊,AMD將它命名為計算單元(compute unit, CU),一個CU中的兩個核心協(xié)同完成事務(wù)。也就是說,i7是四核心、八線程,F(xiàn)X是四模塊、八核心,本質(zhì)上可以近似認(rèn)為是一樣的。

另外,從圖中還可以看到內(nèi)存控制器、顯示控制器、HyperTransport控制器等,并且還能大致觀察到它們的緩存結(jié)構(gòu),下面當(dāng)然也會細(xì)說。

下面給出SNB/IVB架構(gòu)的全圖。

下面給出BDZ/PDV架構(gòu)的全圖。

可以看到,上面的兩張圖被中間的一條紅線分為兩個區(qū)域。紅線上面的部分叫處理器前端(processor front-end),下面的部分叫處理器后端(processor back-end)。

另外,圖中的方框也被五種顏色區(qū)分開了。前端部分包括紫色和橙色,紫色的為取指(IF)和分支預(yù)測(BP)模塊,橙色的為譯碼(ID)模塊。后端部分包括黃、藍(lán)、綠三種顏色,黃色的為調(diào)度和保留站(RS)模塊,藍(lán)色的為執(zhí)行(EX)模塊,綠色的為存儲(MEM)模塊。我們逐個來討論。

首先看取指和分支預(yù)測模塊。下圖是SNB/IVB的該模塊。

下圖是BDZ/PDV的該模塊。

我們來比較分支預(yù)測機(jī)制,就是圖中的Branch Predictors。

SNB/IVB的分支預(yù)測器有兩級,每個核心有一個。第一級預(yù)測器很小,但速度極快,可以在1CC內(nèi)完成一次分支預(yù)測。第二級則大得多,作為一個后備。預(yù)測器的成分包括:簡單的2-bit預(yù)測器、全局歷史預(yù)測器、循環(huán)退出預(yù)測器。Intel在內(nèi)部自建有一套算法,用于判斷當(dāng)前哪個預(yù)測器的準(zhǔn)確度較高,并選用之。

SNB/IVB的分支目標(biāo)緩存(branch target buffer, BTB)結(jié)構(gòu)目前大多認(rèn)為是1層,具體細(xì)節(jié)未知,但基本上會有多達(dá)8K甚至16K條條目(”reasonably large”)。對于每16個字節(jié)長的代碼段,它能hold住最多4條跳轉(zhuǎn)指令。另外,返回棧的緩存有16條。

當(dāng)然,如果預(yù)測錯誤的話,必然會造成時間損失(因為流水線幾乎會被flush掉),這叫做誤預(yù)測罰時(misprediction penalty)。SNB/IVB的罰時大約為15~17CC。

BDZ/PDV的分支預(yù)測器則是每個模塊有一個,由兩個核心共享,采用本地預(yù)測+全局預(yù)測的混合預(yù)測方式。AMD在其內(nèi)部使用了感知器(perceptron),像神經(jīng)元一樣跟隨并記憶分支結(jié)果,因此在經(jīng)過一段時間的訓(xùn)練過程后,對較長的跳轉(zhuǎn)有較好的表現(xiàn)。但其內(nèi)部并無循環(huán)計數(shù)器,因此對于嵌套較深的循環(huán)表現(xiàn)比較差。

BDZ/PDV的BTB結(jié)構(gòu)是兩層組相連的緩存。L1 BTB有128組*4路=512條,L2 BTB有1024組*5路=5120條。返回棧的緩存則是有24條。誤預(yù)測罰時大約為20~25CC。

我們大致需要知道的是:BP的誤預(yù)測率越高,誤預(yù)測罰時越長,那么整個BP模塊的效率就越低。AMD宣稱BDZ/PDV的BP效率較其上一代的K10(Barcelona/Magny-Cours)架構(gòu)為高,但實際上是相反的。K10的誤預(yù)測罰時只有12~15CC(當(dāng)然,K10是沒有采用比較先進(jìn)的模塊化設(shè)計的),也就是說,在同頻率下,對于那些風(fēng)險比較大的分支,BDZ必須要比K10達(dá)到40%以上的正確預(yù)測率的提升,才能彌補(bǔ)罰時的損失,但這是不可能的事情。相對而言,SNB/IVB的BP效率比較高,預(yù)測器中的一個bit可以對應(yīng)多條分支,并且有了黑科技μop$的加成(下面會提到),誤預(yù)測帶來的損失會更小。

上面有大神在回復(fù)中提到說,推土機(jī)有些像奔騰4時代的NetBurst架構(gòu)。這種說法還是比較中肯的。BDZ雖然沒有NetBurst那么恐怖的流水線級數(shù)(比如Prescott的39級流水線),但仍然比較長,有18~20級,并且分支預(yù)測的時間損失都比較大,都沒有實現(xiàn)“通過提高主頻就可以簡單地提升性能”的設(shè)想。

下面來看取指過程。

對于SNB/IVB而言,當(dāng)下一條指令的地址確定之后,就會同時查詢L1I$和μop$(下面就提到),一次可以從I$取得16B的代碼段。然后,取得的指令會被放入下面的預(yù)譯碼緩存中。預(yù)譯碼器會劃分這些指令的邊界,并對指令前綴進(jìn)行譯碼。隨后,經(jīng)過預(yù)譯碼的指令以每個CC 6條的速度,送入下面的指令隊列中,準(zhǔn)備接受譯碼。SNB/IVB的指令隊列長度未知,但由于早在Merom架構(gòu)時,其長度就達(dá)到了18條,因此幾乎可以肯定這里的指令隊列長于18條。

對于BDZ/PDV而言,取指模塊仍然是由兩個核心共享的。在兩個核心都活動的情況下,它最多可以一次從I$取得32B的代碼段;在一個核心活動的情況下,則是最多20B的代碼段。當(dāng)代碼沒有對齊時,取指的速率會有降低。指令在I$中劃分邊界,然后以32B/CC的速率,進(jìn)入16個條目的指令碼緩存,作用和Intel的指令隊列是相同的。

轉(zhuǎn)—筆吧/坎達(dá)拉克沙

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,763評論 6 539
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,238評論 3 428
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,823評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,604評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 72,339評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,713評論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,712評論 3 445
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,893評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,448評論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,201評論 3 357
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,397評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,944評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,631評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,033評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,321評論 1 293
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,128評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,347評論 2 377

推薦閱讀更多精彩內(nèi)容