從4004到core i7:處理器的進化史 (3)-2-黑箱內部
上個帖子中我們已經大概明白一個處理器里面都有些什么了。在這個帖子中我們把處理器這個黑箱徹底打開。先來看看4004,這可是我們優化的起點:
本文引用地址:http://www.104case.com/article/221769.htm
我們發現在上圖中,麻雀雖小,五臟俱全,幾乎所有結構都具備了。注意下方的timing and control,它就是我上個帖子中提到的控制器。在CPU中,可以將控制器視為一個有限狀態機(finite state machine)。所謂有限狀態機就是下面的結構

這是一個時序電路(sequential logic),換言之它的工作可以由下面的式子來刻畫:
Sn+1=F(Sn,In)
Yn+1=G(Sn+1,In+1)
也就是說它根據上一個狀態和上一個輸入確定下一個狀態,并且根據下一個狀態以及下一個輸入確定下一個輸出。
在控制器當中,輸入就是由指令譯碼器解碼得到的控制信號,輸出就是整個CPU中其他部分的控制信號。
看到最左側的bus buffer了嗎?它實際上就是儲存/加載單元的雛形。
除了ALU和L/S單元以及控制器,還有各類連線,最顯眼的可能就是寄存器了。
寄存器是CPU中速度最快的存儲單元。這不單因為它的實現常常使用手工完成優化的觸發器,而且還因為它就在核心的內部,距離其他部分的連線長度最短。一般來說,寄存器的讀寫只要1個時鐘周期就可以了。可以將寄存器理解為一段程序的首要狀態,這些狀態最頻繁地被讀寫。因此,你不難理解為什么有些愛耍小聰明的編譯器總是變著法子把變量整到寄存器里去了吧。
另外一個值得注意的地方是圖中的Program Counter,PC,程序指針。這個寄存器里的值就是將要取得下一條指令的具體的地址。所以它要和ALU連在一起,因為它總是要不停地遞增。順帶提一句,PC除了各類跳轉(jump)的指令之外一般輕易不會讓用戶賦值。天知道你要干什么不靠譜的事情!
當然我們不能忘了連線(interconnect),在圖中就是那個4-bit bus。總線(bus)是一種易于實現的結構,如果你還記得前面講過的電路,你就會知道只要在一般的邏輯電路和總線之間接一個傳輸門,配合上選通結構就可以正常工作了。但是總線是一種低效的結構,原因很簡單:由于上面的電平是所有人都共享的,所以一時間只能有一個驅動總線的器件。這在4004中也許沒什么大問題,但是當總線上掛載的器件很多的時候可以想象性能有多糟糕。和總線相反的另外一個極端是兩兩互聯。毫無疑問這種連線可以實現最高的效率,但是它卻給每個器件帶來了非常大的復雜度,并且還不是可拓展的:你不可能往這個網絡中無限制地添加器件還保證正確性了。
作為這個簡短的帖子的結尾,我們來看一看4004是怎么計算1+2=?這個問題的吧。在以下的解釋中,我略去了公共的IF,ID,以及PC遞增的環節。
load reg1,mem1 --bus buffer->bus->reg1
load acc,mem2 --bus buffer->bus->accumulator(累加器,也是一個寄存器)
add acc,reg1 --reg1->bus->temp reg(這個寄存器是不可見的);
temp+acc->bus->acc(acc被加上了temp)
store mem3,acc --acc->bus->bus buffer
怎么樣,是不是很累呢?
你也許奇怪為什么ALU只能接在acc和temp之間,為什么結果只能存在acc里。
答案是,intel剛發明4004的時候集成電路還是個新生產物,晶體管的集成在當時還是非常昂貴的。因此當時的考慮并不是時間上的性能,而是晶體管的分時復用,怎樣讓同樣的單元實現最多的功能。
現在你能理解x86指令集中許多看起來奇奇怪怪的限制了吧。沒錯,它們就是這個原始的年代的遺留產物。
評論