CPU核心主要分為兩部分:運算器和控制器。
(一) 運算器
1、 算術邏輯運算單元ALU(Arithmetic and Logic Unit)
ALU主要完成對位元據的定點算術運算(加減乘除)、邏輯運算(與或非異或)以及移位操作。在某些CPU中還有專門用於處理移位操作的移位器。
通常ALU由兩個輸入端和一個輸出端。整數單元有時也稱為IEU(Integer Execution Unit)。我們通常所說的“CPU是XX位的”就是指ALU所能處理的資料的位元。
2、 浮點運算單元FPU(Floating Point Unit)
FPU主要負責浮點運算和高精度整數運算。有些FPU還具有向量運算的功能,另外一些則有專門的向量處理單元。
3、 通用寄存器組
通用寄存器組是一組最快的儲存空間,用來儲存參加運算的運算元和中間結果。
在通用寄存器的設計上,RISC與CISC有著很大的不同:
a) CISC的寄存器通常很少,主要是受了當時硬體成本所限。比如x86指令集只有8個通用寄存 器。所以,CISC的CPU執行是大多數時間是在訪問儲存空間中的資料,而不是寄存器中的。這就拖慢了整個系統的速度。
b) 而RISC系統往往具有非常多的通用 寄存器,並採用了重疊寄存器視窗和寄存器堆等技術使寄存器資源得到充分的利用。
c) 對於x86指令集只支援8個通用寄存器的缺點,Intel和AMD的最新CPU都採用了一種叫做“寄存器重新命名”的技術,這種技術使x86CPU的寄存器可以突破8個的限制,達到32個甚至更多。
d) 不過,相對於RISC來說,這種技術的寄存器操作要多出一個刻度,用來對寄存器進行重新命名。
4、 專用寄存器
專用寄存器通常是一些狀態寄存器,不能通過程式改變,由CPU自己控制,表明某種狀態。
(二) 控制器
運算器只能完成運算,而控制器用於控制著整個CPU的工作。
1、 指令控制器:
指令控制器是控制器中相當重要的部分,它要完成取指令、分析指令等操作,然後交給執行單元(ALU或FPU)來執行,同時還要形成下一條指令的地址。
2、 時序控制器:
時序控制器的作用是為每條指令按時間順序提供控制訊號。時序控制器包括時鐘發生器和倍頻定義單元,其中時鐘發生器由石英晶體振蕩器發出非常穩定的脈衝訊號,就是CPU的主頻;而倍頻定義單元則定義了CPU主頻是儲存空間頻率(匯流排頻率)的幾倍。
3、 匯流排控制器:
匯流排控制器主要用於控制CPU的內外部匯流排,包括地址匯流排、資料匯流排、控制匯流排等等。
4、 中斷控制器:
中斷控制器用於控制各種各樣的插斷要求,並根據優先順序的高低對插斷要求進行排隊,逐個交給CPU處理。
(三) CPU核心的設計
CPU的效能是由什麼決定的呢?單純的一個ALU速度在一個CPU中並不起決定性作用,因為ALU的速度都差不多。而一個CPU的效能表現的決定性因素就在於CPU核心的設計。
1、超標量(Superscalar)
既然無法大幅提高ALU的速度,有什麼替代的方法呢?平行處理的方法又一次產生了強大的作用。所謂的超標量CPU,就是只整合了多個ALU、多個FPU、多個解碼器和多條流水線的CPU,以平行處理的方式來提高效能。
超標量技術應該是很容易理解的,不過有一點需要注意,就是不要去管“超標量”之前的那個數字,比如“9路超標量”,不同的廠商對於這個數字有著不同的定義,更多的這隻是一種商業上的宣傳手段。
2、流水線(Pipeline)
對於一條具體的指令執行過程,通常可以分為五個部分:取指令,指令解碼,取運算元,運算(ALU),寫結果。
其中前三步一般由指令控制器完成,後兩步 則由運算器完成。
按照傳統的方式,所有指令順序執行,那麼先是指令控制器工作,完成第一條指令的前三步,然後運算器工作,完成後兩步,在指令控制器工作, 完成第二條指令的前三步,在是運算器,完成第二條指令的後兩部-----很明顯,當指令控制器工作是運算器基本上在休息,而當運算器在工作時指令控制器卻在休 息,造成了相當大的資源浪費。解決方案很容易想到,當指令控制器完成了第一條指令的前三步後,直接開始第二條指令的操作,運算單元也是。這樣就形成了流水線系統,這是一條2級流水線。
如果是一個超標量系統,假設有三個指令控制單元和兩個運算單元,那麼就可以在完成了第一條指令的取址工作後直接開始第二條指令的取址,這時第一條指令在進行解碼,然後第三條指令取址,第二條指令解碼,第一條指令取運算元……這樣就是一個5級流水線。很顯然,5級流水線的平均理論速度是不用流水線的4 倍。
流水線系統最大限度地利用了CPU資源,使每個組件在每個刻度都工作,大大提高了效率。但是,流水線有兩個非常大的問題:相關和轉移。
在一個流水線系統中,如果第二條指令需要用到第一條指令的結果,這種情況叫做相關。以上面哪個5級流水線為例,當第二條指令需要取運算元時,第一條指 令的運算還沒有完成,如果這時第二條指令就去取運算元,就會得到錯誤的結果。所以,這時整條流水線不得不停頓下來,等待第一條指令的完成。這是很討厭的問 題,特別是對於比較長的流水線,比如20級,這種停頓通常要損失十幾個刻度。目前解決這個問題的方法是亂序執行。亂序執行的原理是在兩條相關指令中插 入不相關的指令,使整條流水線順暢。比如上面的例子中,開始執行第一條指令後直接開始執行第三條指令(假設第三條指令不相關),然後才開始執行第二條指
令,這樣當第二條指令需要取運算元時第一條指令剛好完成,而且第三條指令也快要完成了,整條流水線不會停頓。當然,流水線的阻塞現象還是不能完全避免的, 尤其是當相關指令非常多的時候。
另一個大問題是條件轉移。在上面的例子中,如果第一條指令是一個條件轉移指令,那麼系統就會不清楚下面應該執行那一條指令?這時就必須等第一條指令的 判斷結果出來才能執行第二條指令。條件轉移所造成的流水線停頓甚至比相關還要嚴重的多。所以,現在採用分支預測技術來處理轉移問題。雖然我們的程式中充滿 著分支,而且哪一條分支都是有可能的,但大多數情況下總是選擇某一分支。比如一個迴圈的末尾是一個分支,除了最後一次我們需要跳出迴圈外,其他的時候我們 總是選擇繼續迴圈這條分支。根據這些原理,分支預測技術可以在沒有得到結果之前預測下一條指令是什麼,並執行它。現在的分支預測技術能夠達到90%以上的
正確率,但是,一旦預測錯誤,CPU仍然不得不清理整條流水線並回到分支點。這將損失大量的刻度。所以,進一步提高分支預測的準確率也是正在研究的一 個課題。
越是長的流水線,相關和轉移兩大問題也越嚴重,所以,流水線並不是越長越好,超標量也不是越多越好,找到一個速度與效率的平衡點才是最重要的。
轉載:http://hi.baidu.com/halleyzhang/blog/item/e45ed35c3ebb0442fbf2c09d.html