CPU指令的流水線執行

        指令集是CPU體系架構的重要組成部分。C語言的語法是對解決現實問題的運算和流程的方法的高度概況和抽象,其主要爲算術、邏輯運算和分支控制,而指令集就是對這些抽象的具體支持,彙編只不過是爲了讓開發人員更好地記住指令,但它跟CPU所認的機器碼其實是一一對應的,因此彙編也是低級語言。

        CPU的指令執行一般包括取指、譯碼和執行,這是經典的三級指令執行流水線,教科書上往往以這三種過程來描述,arm7也是。但是現代的CPU設計往往使用更廣泛使用的5級流水線,也就是分爲取指、譯碼、執行、訪存和回寫。爲什麼要分爲5級?這是由流水線的各個階段的時間來決定的。我們可以考慮現實生活的工廠的流水線。

        假設某流水線只有 三個工序,有三個工人A、B、C,則這條生產線的效率就取決於效率最低的那個工人的效率。現假設B做完其負責的工序需要10秒,而A和C完成只需要5秒,總共要完成4個產品。那總時間應該是:5+10*4+5 = 50秒,(第一個5是A先做第一道工序的時間,這時B和C都得等,而最後一個5是C必須要等B全部完成後才能開始)即會出現C在等待,而B一直在忙死忙活的場景。 

        當然,無論怎樣,流水線的執行總比完成沒有流水好,就好比A、B、C負責的工作都由一個人去做,那做完一個得20秒。全部做完得20*4 = 80秒。

        最理性的場景就是三個人做事的效率是一樣的,那就不會出現等待的情況。那現在確實遇到B工作效率最低的問題,怎麼解決呢?就是將B的工作重新分解,平均分成兩個工序,也就是B1和B2,分別都是5秒完成,那完成的總時間是40秒。

         CPU指令的三級流水執行正是遇到各步驟流水時間不均的問題,也就是取指和譯碼往往比較快,而執行包括運算和訪問寄存器、內存或者回寫等功能,因此執行的時間一般比取指和譯碼要長,取指和譯碼可以在單時鐘週期內完成,但執行需要2到3個時鐘週期才能完成。要想得到更高的流水效率,就需要將執行部分分解爲執行(運算等)、訪存(內存)和回寫(寄存器)。

         CPU指令的流水線執行對於軟件開發人員來說,最重要的就是要知道當前PC(程序計數寄存器)的值與當前執行指令的關係。取指指的是CPU根據當前PC的值內存的對應地址去取指令,因此PC值永遠都指的都是當前取指令步驟的地址,而譯碼則是CPU的一部分電路根據取出來的指令機器碼進行譯碼,選擇對應的電路來執行這條執行,如選擇加法電路還是減法電路,還是邏輯與電路等等;執行就是這個電路的執行過程了。

         arm7的流水線示意圖是:

 

             從圖可以看到在T1時刻,CPU的執行電路執行的是MOV指令,而取指電路取的是SUB指令,因此當前執行電路的MOV對應的運行地址應該是當前PC值減8. 如果當前運行的指令是一個函數調用(即BL指令),但返回地址就應該是ADD指令所在的地址,即(PC減4)。

 

        有人問到流水線斷流的問題,補充說明一下,斷流主要有以下情況:

        1)數據相關。如第二條指令需要的數據正好是第一條指令執行的結果。這時第二條必須等待。

        2)分支跳轉。指令分支判斷之後,可能會順序執行,也可能跳轉到其他地方,這時也會引起流水線的斷流。

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章