科技簡章041-什麼是複雜指令集

昨天的文章已經介紹過,所謂指令,就是CPU幹活的最小功能單位;指令集就是一套指令的集合。指令集又分為複雜指令集和精簡指令集,今天先講複雜指令集。

大家都知道所謂的軟體就是程式,程式也是一系列指令的集合,用來指揮計算機硬體執行特定的任務。

但CPU只能識別機器語言,所謂

機器語言就是直接用二進位制程式碼表達的計算機語言,它是用0和1組成的一堆程式碼,有一定的位數,並分為若干段,各段編碼代表不同的含義。

機器字長是指 CPU 一次處理資料的寬度,我們通常所說的 “32位CPU”、“64位CPU” 中的 “32”、“64” 就是機器字長。機器字長主要由運算器、暫存器決定,通常暫存器長度等於機器字長。如32位處理器,每個暫存器能儲存 32bit 資料。

我們現在常用的編寫程式碼的計算機語言很多,比如java、c++等等,它們都需要透過一個“編譯器”將採用java等語言編寫的程式翻譯成機器語言後,才能被CPU識別。之前在講英特爾CPU發家史的時候提到過,比爾蓋茨最早就寫了一個BASIC編譯器來賣,它就能將BASIC語言編譯的程式碼翻譯成機器語言。

這些被翻譯後的程式語言指令集與CPU的指令集也並不是完全一一對應的,CPU的指令集是核心指令集,這些程式還會被細拆成若干核心指令,然後再透過CPU來執行。

複雜指令集誕生於60年代,那個時期的計算機運算速度顯然不夠快、儲存容量顯然也非常的小。而程式不但會佔用記憶體容量,而且CPU在執行任務的時候每次還需要去訪問主存,這就會導致很多的“取指令時間”,執行效率自然就降低。

為了提高計算機的執行速度和執行效率,人們就開始琢磨是不是能把原本軟體常用的功能改為用CPU的指令集完成。

這裡說一下,為什麼用CPU的指令集來執行功能比用軟體更快。

首先,就是上面我們說的,CPU的指令集用的就是機器碼,這裡不需要“翻譯”這個過程,自然能快不少。

第二,就要說到暫存器了。暫存器是CPU的核心之一,它有兩項工作。一是接受控制器的指令,將命令傳達給運算器;二是幫助運算器記錄已經處理或者將要處理的資料。

指令集在暫存器中操作,主頻和CPU是相同的,那就相當於是CPU內部自己操作啊,自然會更快。暫存器的硬體構造通常有兩種,一種是採用觸發器,最小儲存單元由16個電晶體組成;另一種是採用SRAM,最小儲存單元由6個電晶體組成。

無論哪一種硬體構成,都比由一個電容和一個電晶體組成最小單元的DRAM記憶體要快。有人可能就要問,既然觸發器和SRAM更快,為什麼記憶體不用這兩個來做。主要原因當然是成本、面積和功耗。組成的電晶體多,自然在同等容量下更貴、面積更大、功耗更大。

計算機發展早期,人們為了讓計算機更快,就不得不將越來愈多的軟體指令改成CPU指令集,於是,逐漸形成了“複雜指令集”。

但也正是因為複雜的指令集越來越多,用機器碼寫起來實在是太費勁了。而且由於其複雜度高,編譯器在將高階程式語言翻譯成機器語言的時候也更費勁了,不僅費勁還容易出錯。

於是,CPU上發展出了“微程式”,它是由簡單的指令組成的,類似程式設計語言結構的複雜指令。這些微程式

減少了程式設計語言和機器語言之間的語義差別,從而簡化了編譯器的結構。所以,對於有微程式結構的CPU來說,CPU執行的是微程式。

採用微程式,CPU指令集就可以新增更多的指令,不過就是多搞一些微程式而已。

每新出一代CPU,就會有自己新的指令集。但新的CPU不能跑不了之前的軟體啊,所以舊的CPU中的指令集必須在新CPU中繼續保留,這就讓複雜指令集越來越複雜,這樣,才能保證整個系統的相容性。

一開始CPU處理器都是CISC複雜指令集架構,但隨著時間推移,越來越多的指令加入,指令集越搞越複雜。複雜指令集的三個明顯缺陷開始暴露了:

第一、設計實在太複雜了,什麼指令集都需要硬體來實現,這就要求硬體越來越高的整合度。

第二、每個指令的執行時間長短不一,CPU內部很難實現流水作業,如此就算CPU速度提升了但卻避免不了無謂的等待時間。

第三、為了處理複雜指令集,CPU內部需要整合的電晶體越來越多,功耗也是個大問題。

1975年,IBM研究中心的研究員們開始研究複雜指令集的合理性問題,因為人們當時已經不斷髮現,日益複雜的指令集不但實現起來困難,而且還有可能是在降低系統性能。1979年RISC精簡指令集的主張被提出。具體下一章講。