天堂系列97嫩模在线播放_真人直播视频免费网站_日本一区二区久久_国产精品区免费视频_亚洲精品国男人在线视频

您的位置:首頁 > 熱點 >

探秘X86架構CPU流水線

英文原文:A Journey Through the CPU Pipeline

作為程序員,CPU 在我們的工作中扮演了核心角色,因此了解處理器內(nèi)部的工作方式對程序員來說不無裨益。

CPU 是如何工作的呢?一條指令執(zhí)行需要多長時間?當我們討論某個新款處理器擁有 12 級流水線還是 18 級流水線,甚至是更深的 31 級流水線時,這到些都意味著什么呢?

應用程序通常會將 CPU 看作是黑盒子。程序中的指令按照順序依次進入 CPU,執(zhí)行完之后再按順序依次從 CPU 中出來,而內(nèi)部到底發(fā)生了什么,我們通常并不了解。

對我們程序員來說,尤其是對做程序性能調(diào)優(yōu)工作的程序員來說,學習 CPU 內(nèi)部的細節(jié)非常必要。否則,如果你不知道 CPU 的內(nèi)部結構,那如何才能針對 CPU 做性能優(yōu)化?

本文所關注的就是專門針對 X86 處理器流水線的工作原理。

你需要掌握的預備知識

首先,閱讀本文你需要了解編程,最好了解一點匯編語言。如果你還不知道指令指針(instruction pointer)是什么,那么本文對你來說可能有些難。你需要知道什么是寄存器,指令和緩存,如果不明白它們是什么,你需要盡快查找資料了解一下。

第二,CPU 的工作原理是一個非常龐大和復雜的話題,本文僅僅是匆匆一瞥,很難以用一篇文章詳盡敘述。如果我有什么疏漏,請通過評論告訴我。

第三,我僅僅關注英特爾處理器及其 X86 架構。當然除了 X86,還有很多其他架構的處理器。雖然 AMD 公司引入了很多新特性到 X86 架構,但是 X86 架構是 Intel 公司發(fā)明,并且創(chuàng)造了 X86 指令集,其中絕大多數(shù)特性是由 Intel 引入的。所以為了保持敘述的簡單和一致性,我僅關注 Intel 的處理器。

最后,當你讀到這篇文章時,它已經(jīng)是“過時”的了。更新款的處理器已經(jīng)設計出來,其中一些會在未來幾個月之內(nèi)發(fā)布。我很高興技術能如此快速的發(fā)展,我希望有一天所有這些技術都會過時,創(chuàng)造出擁有更驚人計算能力的 CPU.

處理器流水線基礎

從一個非常廣的角度來說,X86 處理器架構在近 35 年來并沒有變化太多。雖然 X86 架構被附加了很多新功能,但是最初的設計(包括幾乎所有最初的指令集)仍然基本上是完整保留的,即使在最新的處理器上仍然被支持。

最初的 8086 處理器支持 14 個寄存器,這些寄存器在如今最新的處理器中仍然存在。這 14 個寄存器中,有 4 個是通用寄存器:AX,BX,CX 和 DX;有 4 個是段寄存器,段寄存器用來輔助指針的實現(xiàn):代碼段(CS),數(shù)據(jù)段(DS),擴展段(ES)和堆棧段(SS);有 4 個是索引寄存器,用來指向內(nèi)存地址:源引用(SI),目的引用(DI),基指針(BP),棧指針(SP);有 1 個寄存器包含狀態(tài)位;最后是最重要的寄存器:指令指針(IP)。

指令指針寄存器是一個擁有特殊功能的指針。指令指針的功能是指向將要運行的下一條指令。

所有的 X86 處理器都按照相同的模式運行。首先,根據(jù)指令指針指向的地址取得下一條即將運行的指令并解析該指令(譯碼)。在譯碼完成后,會有一個指令的執(zhí)行階段。有些指令用來從內(nèi)存讀取數(shù)據(jù)或者向內(nèi)存寫數(shù)據(jù),有些指令用來執(zhí)行計算或者比較等工作。當指令執(zhí)行完成后,這條指令會通過退出(retire)階段并將指令指針修改為下一條指令。

譯碼,執(zhí)行和退出三級流水線組成了 X86 處理器指令執(zhí)行的基本模式。從最初的 8086 處理器到最新的酷睿 i7 處理器都基本遵循了這樣的過程。雖然更新的處理器增加了更多的流水級,但基本的模式?jīng)]有改變。

35 年來發(fā)生了什么改變

相較于現(xiàn)今的標準,最初的處理器設計顯得太過簡單。最初的 8086 處理器的執(zhí)行過程可以簡述為從當前指令指針取得指令,通過譯碼,執(zhí)行最后退出,然后繼續(xù)從指令指針指向的下一條指令處取得指令。

新的處理器增加了新的功能,有些增加了新的指令,有些增加了新的寄存器。我將主要關注和本文主題有關系的改變,這些改變影響了 CPU 指令執(zhí)行的流程。其他的一些變化比如虛擬內(nèi)存或者并行處理雖然都很有意義而且有趣,但是并不在本文主題的范圍內(nèi)。

指令緩存在 1982 年被加入到處理器中。通過指令緩存,處理器可以一次性從內(nèi)存讀取更多指令并放在指令緩存中,而不用每條指令都從內(nèi)存中取。指令緩存僅有幾個字節(jié)大小,只能容納數(shù)條指令,但是因為消除了之后每次取指往返內(nèi)存和處理器的時間,極大的提高的效率

1985 年的 386 處理器引入了數(shù)據(jù)緩存,而且擴展了指令緩存的設計。數(shù)據(jù)訪存請求通過一次性讀取更多的數(shù)據(jù)放在數(shù)據(jù)緩存中,從而提升了性能。而且,數(shù)據(jù)緩存和指令緩存都從幾個字節(jié)擴大到幾千字節(jié)。

19巴久年推出的 i486 處理器引入了五級流水線。這時,在 CPU 中不再僅運行一條指令,每一級流水線在同一時刻都運行著不同的指令。這個設計使得 I486 比同頻率的 386 處理器性能提升了不止一倍。五級流水線中的取指階段將指令從指令緩存中取出(i486 中的指令緩存為 8KB);第二級為譯碼階段,將取出的指令翻譯為具體的功能操作;第三級為轉址階段,用來將內(nèi)存地址和偏移進行轉換;第四級為執(zhí)行階段,指令在該階段真正執(zhí)行運算;第五級為退出階段,運算的結果被寫回寄存器或者內(nèi)存。由于處理器同時運行了多條指令,大大提升了程序運行的性能。

1993 年 Intel 推出了奔騰(Pentium)處理器。由于訴訟問題,Intel 無法繼續(xù)沿用原來的數(shù)字編號。因此,用奔騰替代了 586 作為新款處理器的代號。奔騰處理器相對 i486 處理器對流水線做出了更多修改。奔騰處理器架構增加了第二條獨立的超標量流水線。主流水線工作方式類似于 i486,第二條流水線則并行的運行一些較簡單的指令,比如說定點算術,而且該流水線能更快的進行該運算。

1995 年 Intel 推出了奔騰 Pro (Pentium Pro)處理器。和之前的處理器相比,奔騰 Pro 采用了完全不同的設計。該處理器采用了諸多新特性以提高性能,包括亂序(Out-of-Order, OOO)執(zhí)行的部件以及猜測執(zhí)行。流水線擴展到了 12 級,而且引入了“超標量流水線”的概念,使得許多指令可以被同時處理。我們稍后將詳盡的介紹亂序執(zhí)行的部件。

在 1995-2002 年之間,亂序執(zhí)行部件經(jīng)過了數(shù)次重大改進。處理器中加入了更多的寄存器;單指令多數(shù)據(jù)(Single Instruction Multiple Data, or SIMD)的引入使得一條指令可以進行多組數(shù)據(jù)運算;現(xiàn)有的緩存變得更大而且引入了新的緩存;有些流水級被拆分成更多流水級,有些流水級被合并,使得更加適合實際的應用。這些改變對整體性能的提升有重要作用,但它們都沒有從根本影響數(shù)據(jù)在處理器中的流動方式。

2002 年發(fā)布的奔騰 4 處理器引入了超線程技術。亂序執(zhí)行部件的設計使得指令被執(zhí)行的速度比處理器能夠提供指令的速度更快。因此對于大部分應用,CPU 的亂序執(zhí)行部件在大部分時間處于空閑狀態(tài),甚至在高負載的情況下也不能充分利用。為了讓指令流能充分的流入亂序執(zhí)行部件,Intel 加入了第二套前端部件(譯注:在處理器結構中,前端是指取指,譯碼,寄存器重命名等模塊,經(jīng)過前端部件的處理后,指令等待發(fā)射進入亂序執(zhí)行部件)。雖然實際上只有一個亂序執(zhí)行部件,但對于操作系統(tǒng)來說,它能看到兩個處理器。前端部件包含兩組同樣功能的 X86 寄存器,兩個指令譯碼器根據(jù)兩個指令指針指向的地址分別處理。所有的指令被一個共享的亂序執(zhí)行部件執(zhí)行,但對應用程序來說并不知情。當亂序執(zhí)行部件執(zhí)行完成,像之前一樣退出流水線后,最終結果返回虛擬的兩個處理器。

2006 年 Intel 發(fā)布了酷睿(Core)微架構。為了品牌效應,它被稱做酷睿2(二總比一好)。令人驚訝的是,處理器頻率不升反降,而且超線程也被去掉了。通過降低時鐘頻率,每一級流水線可以做更多工作。亂序執(zhí)行部件也被擴展的更寬。各種不同的緩存和隊列都相應做的更大。而且處理器被重新設計,以適應雙核和四核的共享緩存結構。

2008 年,Intel 開始用酷睿 i3, i5, i7 的方式來命名新的處理器。新處理器重新引入了超線程。這三個系列的處理器主要區(qū)別在于內(nèi)部緩存大小不同。

未來的處理器:Intel 的下一代微結構被稱為 Haswell.Haswell 據(jù)稱將于 2013 年發(fā)布。目前已知的文檔說明它將擁有 14 級流水級的亂序執(zhí)行部件,所以它仍然遵循從奔騰 Pro 以來的基本設計思路。

那么,流水線到底是什么?亂序執(zhí)行部件是什么?他們?nèi)绾翁嵘颂幚砥鞯男阅苣?

CPU 指令流水線

根據(jù)之前描述的基礎,指令進入流水線,通過流水線處理,從流水線出來的過程,對于我們程序員來說,是比較直觀的。

I486 擁有五級流水線。分別是:取指(Fetch),譯碼(D1, main decode),轉址(D2, translate),執(zhí)行(EX, execute),寫回(WB)。某個指令可以在流水線的任何一級。

但是這樣的流水線有一個明顯的缺陷。對于下面的指令代碼,它們的功能是將兩個變量的內(nèi)容進行交換。

XOR a, b

XOR b, a

XOR a, b

從 8086 直到 386 處理器都沒有流水線。處理器一次只能執(zhí)行一條指令。再這樣的架構下,上面的代碼執(zhí)行并不會存在問題。

但是 i486 處理器是首個擁有流水線的 x86 處理器,它執(zhí)行上面的代碼會發(fā)生什么呢?當你一下去觀察很多指令在流水線中運行,你會覺得混亂,所以你需要回頭參考上面的圖。

第一步是第一條指令進入取指階段;然后在第二步第一條指令進入譯碼階段,同時第二條指令進入取指階段;第三步第一條指令進入轉址階段,第二條指令進入譯碼階段,第三條指令進入取指階段。但是在第四步會出現(xiàn)問題,第一條指令會進入執(zhí)行階段,而其他指令卻不能繼續(xù)向前移動。第二條 xor 指令需要第一條 xor 指令計算的結果a,但是直到第一條指令執(zhí)行完成才會寫回。所以流水線的其他指令就會在當前流水級等待直到第一條指令的執(zhí)行和寫回階段完成。第二條指令會等待第一條指令完成才能進入流水線下一級,同樣第三條指令也要等待第二條指令完成。

這個現(xiàn)象被稱為流水線阻塞或者流水線氣泡。

另外一個關于流水線的問題是有些指令執(zhí)行速度快,有些指令執(zhí)行速度慢。這個問題在奔騰處理器的雙流水線架構下顯得更加明顯。

奔騰 Pro 擁有 12 級流水線。當這個數(shù)字被首次宣布后,所有的程序員都倒抽了一口氣,因為他們知道超標量流水線是如何工作的。如果 Intel 仍然按照以前的思路設計超標量流水線的話,流水線的阻塞和執(zhí)行速度慢的指令會嚴重影響執(zhí)行速度。但同時,Intel 宣布了完全不同的流水線設計,叫做亂序執(zhí)行部件(Out-of-Order core)。單從敘述上很難理解這些改變帶來的好處,但 Intel 確信這些改進是令人激動的。

讓我們來更深入的看看這個亂序執(zhí)行的部件吧!

亂序執(zhí)行流水線

在描述亂序執(zhí)行流水線時,往往是一圖勝千言。所以我們主要以圖例進行介紹。

CPU 流水線圖例

I486 處理器擁有 5 級流水線。這種設計在現(xiàn)實世界中的其他處理器中很常見,而且效率不錯。

而奔騰處理器的流水線比 i486 更好。兩條流水線可以并行運行,而且每條流水線可以同時有多條指令在不同流水級執(zhí)行。它幾乎可以同時執(zhí)行比 i486 多一倍的指令。

能夠快速完成的指令需要等待前面執(zhí)行慢的指令即使在并行流水線中也仍然是一個問題。流水線仍然是線性的,導致處理器面臨性能瓶頸難以逾越。

亂序執(zhí)行部件和之前處理器設計中的線性通路有很大不同,它增加了一些復雜度,引入了非線性的通路。

標簽:

相關閱讀