CPU的發展史
CPU的工作原理
總的來說,CPU從內存中一條一條地取出指令和相應的數據,按指令操作碼的規定,對數據進行運算處理,直到程序執行完畢為止。
CPU指令周期
指令周期是取出并執行一條指令的時間。指令周期常常有若干個CPU周期,CPU周期也稱為機器周期,由于CPU訪問一次內存所花費的時間較長,因此通常用內存中讀取一個指令字的最短時間來規定CPU周期。
一條指令還是相當復雜的,處理器在一個時鐘周期內肯定是完不成的,可能需要好多個時鐘周期來完成執行。如果這樣讓處理器執行完一條指令,再去執行另一條,處理器的效率是很低的,假如一條指令是5個時鐘周期完成,對于500MHZ的處理器串行運行指令,1秒內取指100000000次。
因此處理器引入了流水線技術,將一條指令劃分為多個功能,由不同的功能部件來執行,并且這些功能部件可以并行工作。
流水線技術
CPU在工作時,需要將一條指令分為多個步驟依次執行(注意硬件不同有可能不一樣),由于每一個步會使用到不同的硬件操作,比如取指時會只有PC寄存器和存儲器,譯碼時會執行到指令寄存器組,執行時會執行ALU(算術邏輯單元)、寫回時使用到寄存器組。為了提高硬件利用率,CPU指令是按流水線技術來執行的,如下:
從圖中可以看出當指令1還未執行完成時,第2條指令便利用空閑的硬件開始執行,這樣做是有好處的,如果每個步驟花費1ms,那么如果第2條指令需要等待第1條指令執行完成后再執行的話,則需要等待5ms,但如果使用流水線技術的話,指令2只需等待1ms就可以開始執行了,這樣就能大大提升CPU的執行性能。
理想情況下,CPU按照流水線執行指令,然而指令流水線除了在資源不足的情況下會卡住之外,指令之間的相關性也是導致流水線阻塞的重要原因。
雖然流水線技術可以大大提升CPU的性能,但不幸的是一旦出現流水中斷,所有硬件設備將會進入一輪停頓期,當再次彌補中斷點可能需要幾個周期,這樣性能損失也會很大,就好比工廠組裝手機的流水線,一旦某個零件組裝中斷,那么該零件往后的工人都有可能進入一輪或者幾輪等待組裝零件的過程。因此我們需要盡量阻止指令中斷的情況,指令重排就是其中一種優化中斷的手段。
指令亂序
指令流水線并不是串行的,并不會因為一個耗時很長的指令在“執行”階段呆很長時間,而導致后續的指令都卡在“執行”之前的階段上。相反,流水線是并行的,多個指令可以同時處于同一個階段,只要CPU內部相應的處理部件未被占滿即可。
然而,這樣一來,亂序可能就產生了。比如一條加法指令原本出現在一條除法指令的后面,但是由于除法的執行時間很長,在它執行完之前,加法可能先執行完了。再比如兩條訪存指令,可能由于第二條指令命中了cache而導致它先于第一條指令完成。
一般情況下,指令亂序并不是CPU在執行指令之前刻意去調整順序。CPU總是順序的去內存里面取指令,然后將其順序的放入指令流水線。但是指令執行時的各種條件,指令與指令之間的相互影響,可能導致順序放入流水線的指令,最終亂序執行完成。這就是所謂的“順序流入,亂序流出”。
CPU的亂序執行并不是任意的亂序,而是以保證程序上下文因果關系為前提的。有了這個前提,CPU執行的正確性才有保證。
相比于CPU的亂序,編譯器的亂序才是真正對指令順序做了調整。但是編譯器的亂序也必須保證程序上下文的因果關系不發生改變。