從4004到core i7:處理器的進(jìn)化史 (3)-2-黑箱內(nèi)部
上個(gè)帖子中我們已經(jīng)大概明白一個(gè)處理器里面都有些什么了。在這個(gè)帖子中我們把處理器這個(gè)黑箱徹底打開(kāi)。先來(lái)看看4004,這可是我們優(yōu)化的起點(diǎn):
本文引用地址:http://m.butianyuan.cn/article/221769.htm
我們發(fā)現(xiàn)在上圖中,麻雀雖小,五臟俱全,幾乎所有結(jié)構(gòu)都具備了。注意下方的timing and control,它就是我上個(gè)帖子中提到的控制器。在CPU中,可以將控制器視為一個(gè)有限狀態(tài)機(jī)(finite state machine)。所謂有限狀態(tài)機(jī)就是下面的結(jié)構(gòu)

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