從4004到core i7:處理器的進(jìn)化史 (3)-2-黑箱內(nèi)部
上個帖子中我們已經(jīng)大概明白一個處理器里面都有些什么了。在這個帖子中我們把處理器這個黑箱徹底打開。先來看看4004,這可是我們優(yōu)化的起點:
本文引用地址:http://www.ex-cimer.com/article/221769.htm我們發(fā)現(xiàn)在上圖中,麻雀雖小,五臟俱全,幾乎所有結(jié)構(gòu)都具備了。注意下方的timing and control,它就是我上個帖子中提到的控制器。在CPU中,可以將控制器視為一個有限狀態(tài)機(jī)(finite state machine)。所謂有限狀態(tài)機(jī)就是下面的結(jié)構(gòu)
這是一個時序電路(sequential logic),換言之它的工作可以由下面的式子來刻畫:
Sn+1=F(Sn,In)
Yn+1=G(Sn+1,In+1)
也就是說它根據(jù)上一個狀態(tài)和上一個輸入確定下一個狀態(tài),并且根據(jù)下一個狀態(tài)以及下一個輸入確定下一個輸出。
在控制器當(dāng)中,輸入就是由指令譯碼器解碼得到的控制信號,輸出就是整個CPU中其他部分的控制信號。
看到最左側(cè)的bus buffer了嗎?它實際上就是儲存/加載單元的雛形。
除了ALU和L/S單元以及控制器,還有各類連線,最顯眼的可能就是寄存器了。
寄存器是CPU中速度最快的存儲單元。這不單因為它的實現(xiàn)常常使用手工完成優(yōu)化的觸發(fā)器,而且還因為它就在核心的內(nèi)部,距離其他部分的連線長度最短。一般來說,寄存器的讀寫只要1個時鐘周期就可以了??梢詫⒓拇嫫骼斫鉃橐欢纬绦虻氖滓獱顟B(tài),這些狀態(tài)最頻繁地被讀寫。因此,你不難理解為什么有些愛耍小聰明的編譯器總是變著法子把變量整到寄存器里去了吧。
另外一個值得注意的地方是圖中的Program Counter,PC,程序指針。這個寄存器里的值就是將要取得下一條指令的具體的地址。所以它要和ALU連在一起,因為它總是要不停地遞增。順帶提一句,PC除了各類跳轉(zhuǎn)(jump)的指令之外一般輕易不會讓用戶賦值。天知道你要干什么不靠譜的事情!
當(dāng)然我們不能忘了連線(interconnect),在圖中就是那個4-bit bus。總線(bus)是一種易于實現(xiàn)的結(jié)構(gòu),如果你還記得前面講過的電路,你就會知道只要在一般的邏輯電路和總線之間接一個傳輸門,配合上選通結(jié)構(gòu)就可以正常工作了。但是總線是一種低效的結(jié)構(gòu),原因很簡單:由于上面的電平是所有人都共享的,所以一時間只能有一個驅(qū)動總線的器件。這在4004中也許沒什么大問題,但是當(dāng)總線上掛載的器件很多的時候可以想象性能有多糟糕。和總線相反的另外一個極端是兩兩互聯(lián)。毫無疑問這種連線可以實現(xiàn)最高的效率,但是它卻給每個器件帶來了非常大的復(fù)雜度,并且還不是可拓展的:你不可能往這個網(wǎng)絡(luò)中無限制地添加器件還保證正確性了。
作為這個簡短的帖子的結(jié)尾,我們來看一看4004是怎么計算1+2=?這個問題的吧。在以下的解釋中,我略去了公共的IF,ID,以及PC遞增的環(huán)節(jié)。
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之間,為什么結(jié)果只能存在acc里。
答案是,intel剛發(fā)明4004的時候集成電路還是個新生產(chǎn)物,晶體管的集成在當(dāng)時還是非常昂貴的。因此當(dāng)時的考慮并不是時間上的性能,而是晶體管的分時復(fù)用,怎樣讓同樣的單元實現(xiàn)最多的功能。
現(xiàn)在你能理解x86指令集中許多看起來奇奇怪怪的限制了吧。沒錯,它們就是這個原始的年代的遺留產(chǎn)物。
評論