我在第5講講計算機指令的時候,給你看過MIPS體系結構計算機的機器指令格式。MIPS的指令都是固定的32位長度,若是要用一個打孔卡來表示,並不複雜。算法
第6講的時候,我帶你編譯了一些簡單的C語言程序,看了x86體系結構下的彙編代碼。眼尖的話,你應該能發現,每一條機器碼的長度是不同的。ubuntu
而CPU的指令集裏的機器碼是固定長度仍是可變長度,也就是 複雜指令集(Complex Instruction SetComputing,簡稱CISC)和 精簡指令集(Reduced Instruction Set Computing,簡稱RISC)這兩種風格的指令集一個最重要的差異。那今天咱們就來看複雜指令集和精簡指令集之間的對比、差別以及歷史糾葛。設計模式
在計算機歷史的早期,其實沒有什麼CISC和RISC之分。或者說,全部的CPU其實都是CISC。緩存
雖然馮·諾依曼高屋建瓴地提出了存儲程序型計算機的基礎架構,可是實際的計算機設計和製造仍是嚴格受硬件層面的限制。當時的計算機很慢,存儲空間也很小。
《人月神話》這本軟件工程界的名著,講的是花了好幾年設計IBM 360這臺計算機的經驗。IBM 360的最低配置,每秒只能運行34500條指令,只有8K的內
存。爲了讓計算機可以作儘可能多的工做,每個字節乃至每個比特都特別重要。bash
因此,CPU指令集的設計,須要仔細考慮硬件限制。爲了性能考慮,不少功能都直接經過硬件電路來完成。爲了少用內存,指令的長度也是可變的。
就像算法和數據結構裏的赫夫曼編碼(Huffman coding)同樣,經常使用的指令要短一些,不經常使用的指令能夠長一些。那個時候的計算機,想要用盡量少的內存空間,
存儲儘可能多的指令。服務器
不過,歷史的車輪滾滾向前,計算機的性能愈來愈好,存儲的空間也愈來愈大了。到了70年代末,RISC開始登上了歷史的舞臺。當時,UC Berkeley的大衛·帕特森(David Patterson)教授發現,
實際在CPU運行的程序裏,80%的時間都是在使用20%的簡單指令。因而,他就提出了RISC的理念。自此以後,RISC類型的CPU開始快速蓬勃發展。數據結構
我常常推薦的課後閱讀材料,有很多是來自《計算機組成與設計:硬件/軟件接口》和《計算機體系結構:量化研究方法》這兩本教科書。此外,他還在2017年得到了圖靈獎。架構
RISC架構的CPU的想法其實很是直觀。既然咱們80%的時間都在用20%的簡單指令,那咱們能不能只要那20%的簡單指令就行了呢?答案固然是能夠的。由於指令數量多,
計算機科學家們在軟硬件兩方面都受到了不少挑戰。ionic
咱們要想支持更多的複雜指令,CPU裏面的電路就要更復雜,設計起來也就更困難。更復雜的電路,在散熱和功耗層面,也會帶來更大的挑戰。性能
支持更多的複雜指令,編譯器的優化就變得更困難。畢竟,面向2000個指令來優化編譯器和麪向500個指令來優化編譯器的困難是徹底不一樣的。
因而,在RISC架構裏面,CPU選擇把指令「精簡」到20%的簡單指令。而原先的複雜指令,則經過用簡單指令組合起來來實現,讓軟件來實現硬件的功能。這樣,CPU的整個硬件設計就會變得更簡單了,在硬件層面提高性能也會變得更容易了。
RISC的CPU裏完成指令的電路變得簡單了,因而也就騰出了更多的空間。這個空間,經常被拿來放通用寄存器。由於RISC完成一樣的功能,執行的指令數量要比CISC多,因此,
若是須要反覆從內存裏面讀取指令或者數據到寄存器裏來,那麼不少時間就會花在訪問內存上。因而,RISC架構的CPU每每就有更多的通用寄存器。
除了寄存器這樣的存儲空間,RISC的CPU也能夠把更多的晶體管,用來實現更好的分支預測等相關功能,進一步去提高CPU實際的執行效率。
總的來講,對於CISC和RISC的對比,咱們能夠一塊兒回到第4講講的程序運行時間的公式:
程序的CPU執行時間=指令數 × CPI × Clock Cycle Time
CISC的架構,其實就是經過優化指令數,來減小CPU的執行時間。
而RISC的架構,實際上是在優化CPI。由於指令比較簡單,須要的時鐘週期就比較少。
由於RISC下降了CPU硬件的設計和開發難度,因此從80年代開始,大部分新的CPU都開始採用RISC架構。從IBM的PowerPC,到SUN的SPARC,都是RISC架構。
全部人看到仍然採用CISC架構的Intel CPU,均可以批評一句「Complex and messy」。可是,爲何不管是在PC上,仍是服務器上,仍然是Intel成爲最後的贏家呢?
面對這麼多負面評價的Intel,天然也不能無動於衷。更況且,x86架構的問題並不能說明Intel的工程師不夠厲害。事實上,在整個CPU設計的領域,Intel集中了大量優秀的人才。不管是成功的Pentium時代引入的超標量設計,仍是失敗的Pentium 4時代引入的超線程技術,都是異常精巧的工程實現。
而x86架構所面臨的種種問題,其實都來自於一個最重要的考量,那就是指令集的向前兼容性。由於x86在商業上太成功了,因此市場上有大量的Intel CPU。
而圍繞着這些CPU,又有大量的操做系統、編譯器。這些系統軟件只支持x86的指令集,就好比著名的Windows 95。而在這些系統軟件上,又有各類各樣的應用軟件。
若是Intel要放棄x86的架構和指令集,開發一個RISC架構的CPU,面臨的第一個問題就是全部這些軟件都是不兼容的。事實上,Intel並不是沒有嘗試過在x86以外另起爐竈,這其實就是我在第26講介紹的安騰處理器。當時,Intel想要在CPU進入64位的時代的時候,丟掉x86的歷史包袱,因此推出了全新的IA-64的架構。可是,卻由於不兼容x86的指令集,遭遇了重大的失敗。
反而是AMD,趁着Intel研發安騰的時候,推出了兼容32位x86指令集的64位架構,也就是AMD64。若是你如今在Linux下安裝各類軟件包,必定常常會看到像下面這樣帶有AMD64字樣的內容。這是由於x86下的64位的指令集x86-64,並非Intel發明的,而是AMD發明的。
Get:1 http://archive.ubuntu.com/ubuntu bionic/main amd64 fontconfig amd64 2.12.6-0ubuntu2 [169 kB]
花開兩朵,各表一枝。Intel在開發安騰處理器的同時,也在不斷借鑑其餘RISC處理器的設計思想。既然核心問題是要始終向前兼容x86的指令集,那麼咱們能不能不修改指令集,可是讓CISC風格的指令集,用RISC的形式在CPU裏面運行呢?
因而,從Pentium Pro時代開始,Intel就開始在處理器裏引入了 微指令(Micro-Instructions/Micro-Ops) 架構。而微指令架構的引入,也讓CISC和RISC的分界變得模糊了。
在微指令架構的CPU裏面,編譯器編譯出來的機器碼和彙編代碼並無發生什麼變化。但在指令譯碼的階段,指令譯碼器「翻譯」出來的,再也不是某一條CPU指令。
譯碼器會把一條機器碼,「 翻譯」成好幾條「微指令」。這裏的一條條微指令,就再也不是CISC風格的了,而是變成了固定長度的RISC風格的了。
這些RISC風格的微指令,會被放到一個微指令緩衝區裏面,而後再從緩衝區裏面,分發給到後面的超標量,而且是亂序執行的流水線架構裏面。
不過這個流水線架構裏面接受的,就不是複雜的指令,而是精簡的指令了。在這個架構裏,咱們的指令譯碼器至關於變成了設計模式裏的一個
「適配器」(Adaptor)。這個適配器,填平了CISC和RISC之間的指令差別。
不過,凡事有好處就有壞處。這樣一個可以把CISC的指令譯碼成RISC指令的指令譯碼器,比原來的指令譯碼器要複雜。這也就意味着更復雜的電路和更長的譯碼時間:
原本覺得能夠經過RISC提高的性能,結果又有一部分浪費在了指令譯碼上。針對這個問題,咱們有沒有更好的辦法呢?
我在前面說過,之因此你們認爲RISC優於CISC,來自於一個數字統計,那就是在實際的程序運行過程當中,有80%運行的代碼用着20%的經常使用指令。這意味着,
CPU裏執行的代碼有很強的局部性。而對於有着很強局部性的問題,常見的一個解決方案就是使用緩存。因此,Intel就在CPU裏面加了一層L0 Cache。
這個Cache保存的就是指令譯碼器把CISC的指令「翻譯」成RISC的微指令的結果。因而,在大部分狀況下,CPU均可以從Cache裏面拿到譯碼結果,而不須要讓譯碼器
去進行實際的譯碼操做。這樣不只優化了性能,由於譯碼器的晶體管開關動做變少了,還減小了功耗。
由於「微指令」架構的存在,從Pentium Pro開始,Intel處理器已經不是一個純粹的CISC處理器了。它一樣融合了大量RISC類型的處理器設計。不過,因爲Intel自己在CPU層面作的大量優化,
好比亂序執行、分支預測等相關工做,x86的CPU始終在功耗上仍是要遠遠超過RISC架構的ARM,因此最終在智能手機崛起替代PC的時代,落在了ARM後面。
2017年,ARM公司的CEO Simon Segards宣佈,ARM累積銷售的芯片數量超過了1000億。做爲一個從12我的起步,在80年代想要獲取Intel的80286架構受權來製造CPU的公司,ARM是如何在移動端把本身的芯片塑形成了最終的霸主呢?
ARM這個名字如今的含義,是「Advanced RISC Machines」。你從名字就可以看出來,ARM的芯片是基於RISC架構的。不過,ARM可以在移動端打敗Intel,
並非由於RISC架構。
到了21世紀的今天,CISC和RISC架構的分界已經沒有那麼明顯了。Intel和AMD的CPU也都是採用譯碼成RISC風格的微指令來運行。ARM的芯片,
而一條指令一樣須要多個時鐘週期,有亂序執行和多發射。我甚至看到過這樣的評價,「ARM和RISC的關係,只有在名字上」。
一個4核的Intel i7的CPU,設計的時候功率就是130W。而一塊ARM A8的單個核心的CPU,設計功率只有2W。二者之間差出了100倍。
在移動設備上,功耗是一個遠比性能更重要的指標,畢竟咱們不能隨時在身上帶個發電機。ARM的CPU,主頻更低,晶體管更少,高速緩存更小,
亂序執行的能力更弱。全部這些,都是爲了功耗所作的妥協。
ARM並無本身壟斷CPU的生產和製造,只是進行CPU設計,而後把對應的知識產權受權出去,讓其餘的廠商來生產ARM架構的CPU。
它甚至還容許這些廠商能夠基於ARM的架構和指令集,設計屬於本身的CPU。像蘋果、三星、華爲,它們都是拿到了基於ARM體系架構設計和製造CPU的受權。ARM本身
只是收取對應的專利受權費用。多個廠商之間的競爭,使得ARM的芯片在市場上價格很便宜。因此,儘管ARM的芯片的出貨量遠大於Intel,可是收入和利潤卻比不上Intel。
不過,ARM並非開源的。因此,在ARM架構逐漸壟斷移動端芯片市場的時候,「開源硬件」也慢慢發展起來了。
一、一方面,MIPS在2019年宣佈開源
二、另外一方面,從UC Berkeley發起的RISC-V項目也愈來愈受到你們的關注。而RISC概念的發明人,圖靈獎的得主大衛·帕特森教授從伯克利退休以後,
成了RISC-V國際開源實驗室的負責人,開始推進RISC-V這個「CPU屆的Linux」的開發。能夠想見,將來的開源CPU,也多半會像Linux同樣,
逐漸成爲一個業界的主流選擇。若是想要「打造一個屬於本身CPU」,不可不關注這個項目
這一講,我從RISC和CISC架構以前的差別提及,講到RISC的指令是固定長度的,CISC的指令是可變長度的。RISC的指令集裏的指令數少,
並且單個指令只完成簡單的功能,因此被稱爲「精簡」。CISC裏的指令數多,爲了節約內存,直接在硬件層面可以完成複雜的功能,因此被稱爲「複雜」。
RISC的經過減小CPI來提高性能,而CISC經過減小須要的指令數來提高性能。
而後,咱們進一步介紹了Intel的x86 CPU的「微指令」的設計思路。「微指令」使得咱們在機器碼層面保留了CISC風格的x86架構的指令集。
可是,經過指令譯碼器和L0緩存的組合,使得這些指令能夠快速翻譯成RISC風格的微指令,使得實際執行指令的流水線能夠用RISC的架構來搭建。
使用「微指令」設計思路的CPU,不能再稱之爲CISC了,而更像一個RISC和CISC融合的產物。
過去十年裏,Intel仍然把持着PC和服務器市場,可是更多的市場上的CPU芯片來自基於ARM架構的智能手機了。而在ARM彷佛已經壟斷了移動CPU市場的時候,開源的RISC-V出現了,也給了計算機工程師們新的設計屬於本身的CPU的機會。