程序是如何在 CPU 中運行的(三)
筆者能力有限,如果文章出現(xiàn)錯誤的地方歡迎各位朋友能夠給我指出來,我將不勝感激,謝謝~
前言
在之前的兩篇文章中,在 程序是如何在 CPU 中運行的(一)中講述了一條一條指令和數(shù)據(jù)是如何在 CPU 中被運行的,在 程序是如何在 CPU 中運行的 (二)中以 PC 寄存器為中心,從匯編語言的角度闡述了程序是如何在 CPU 中有序執(zhí)行的,該篇文章講述流水線機制在 CPU 中的應用。
相關(guān)概念
在進入流水線的講解之前,有必要知道兩個概念,一個是指令周期,一個是時鐘周期。
指令周期:指令周期的意思從其名稱就能看出來,就是運行一條指令的時間,筆者在該系列文章的第一篇中說到一條指令的運行能夠大致分為三個階段:取指 -> 譯碼 -> 執(zhí)行,也就是說這三個階段執(zhí)行的總的時間就是指令周期,也可以用下面這樣的一張圖表示,循環(huán)的執(zhí)行取指,譯碼,執(zhí)行的周期就稱之為指令周期。
指令周期 時鐘周期:時鐘周期就是我們 CPU 的主頻,也就是晶振帶來的每一次“滴答”,就是時鐘周期時間。
了解了這兩個概念之后,我們首先來看單指令周期處理器。
單指令周期處理器
在引入流水線機制之前,先來看看單指令周期處理器,之所以稱之為單指令周期處理器,是因為這樣機制的處理器在運行一條指令的時候,從取指到譯碼到執(zhí)行,不能有第二條指令的加入,也就是說如果前后有兩條指令需要運行,那第二條指令的運行必須等待第一條指令運行完畢之后才能得到運行。
前文所述一條指令大致可以分為三個階段執(zhí)行,而這個過程的執(zhí)行,至少都需要一個時鐘周期,因為在取指的時候我們的 PC 指針寄存器在一個時鐘周期的驅(qū)動下遞增,從而實現(xiàn)下一條指令的取指,同樣的,為了盡可能地提高 CPU 效率,我們也希望指令的運行能夠在一個時鐘周期內(nèi)完成,既然所有的指令的運行都在一個時鐘周期內(nèi)運行,但是指令各有不同,有的指令執(zhí)行的時間長,有的指令執(zhí)行的時間短,因此,為了兼顧所有指令都能夠得到運行,那么時鐘周期就應該滿足執(zhí)行時間最長的指令的運行,下面展示了三條不同的指令在一個時鐘周期內(nèi)所占的時間。
通過上圖我們可以明顯的看到采用單指令周期機制的弊端,時鐘周期受到最長執(zhí)行時間指令的影響,而對于執(zhí)行時間較短的指令來說,又會有大部分時間處于啥也干不了的狀態(tài),浪費了資源,這樣的機制雖然使得每一條指令都在一個時鐘周期內(nèi)就執(zhí)行完畢了,但是也降低了 CPU 的主頻,因為如果太高的話,有些復雜的指令就不能執(zhí)行完。
基于此,也就有了流水線技術(shù)的出現(xiàn)。
流水線設(shè)計
流水線的概念來源于工業(yè)制造領(lǐng)域,可以以汽車裝配為例子來解釋流水線的工作方式,假設(shè)裝配一輛汽車需要四個步驟:沖壓 -> 焊接 -> 涂裝 -> 總裝,最簡單的方式就是先裝配一輛汽車,裝配完一輛之后,在裝下一輛,這樣的方式就類似我們上述講的單指令周期處理器的工作方式。所以為了使得工作效率提高,人們提出了流水線的工作方式,也就是說當?shù)谝惠v汽車裝配到第二道工序(焊接)的時候,第二輛汽車開始第一道工序(沖壓),這樣也就不會使得第一輛汽車裝配完了之后才裝配第二輛汽車,大大地提高了工作效率。
那么 CPU 又是如何以流水線機制運行的呢?我們在前文一直在涉及到一個概念,就是說一條指令的運行大致可以分為三個階段:取址 ->譯碼 -> 執(zhí)行,在這里我們將其再進行細分,因為在整個的執(zhí)行過程中,還包括從寄存器或者內(nèi)存中讀取數(shù)據(jù),通過 ALU 進行計算,再將結(jié)果寫回到寄存器或者內(nèi)存中,所以,也就是說一條指令的運行也可以細分為五個階段,如下圖所示:
這細分的各個步驟就像汽車裝配的各個工序,在單指令周期中,必須等一條指令運行完上述所有的步驟之后,才進行下一條指令的運行,但是引入流水線之后,當?shù)谝粭l指令執(zhí)行到第二個步驟(譯碼)的時候,第二條指令就可以執(zhí)行第一個步驟(取指)了,詳細地運行步驟如下圖所示:
通過上圖可以很清楚地看到指令流水線的執(zhí)行過程,這里要指出的一點是由于上圖將一條指令的執(zhí)行過程拆分成了五個步驟來執(zhí)行,所以上述所示的流水線也被稱之為五級流水線,在圖中我們可以看到取指和譯碼兩個步驟不是緊挨著的,這是因為譯碼這個步驟執(zhí)行的時間要短于取指執(zhí)行的時間,所以在執(zhí)行譯碼之前要等待一會兒。另外,圖中,筆者用紅色箭頭標注了一個時鐘周期所對應的指令,可以看到在這個時鐘周期里運行著五條指令的不同階段。因此,對于五級流水線的定義也可以是這樣的:五級的流水線,就表示我們在同一個時鐘周期里面,同時運行五條指令的不同階段。至此,關(guān)于流水線的基本概念就介紹完了,下面,我們來看一下,使用流水線相和單指令周期運行同樣的指令的差異。
單指令周期和流水線的比較
首先,我們看這樣一個例子,我們順序執(zhí)行三條指令:
一條整數(shù)的加法,需要 200ps
一條整數(shù)的乘法,需要 300ps
一條浮點數(shù)的乘法,需要 600ps
根據(jù)前文所述,單指令周期處理器的時鐘周期取決于執(zhí)行時間最長的指令,在這里也就是 600 ps,那么在單指令周期下三條指令的執(zhí)行過程是這樣的:
通過上圖我們可以看到受到最長執(zhí)行時間指令的影響,現(xiàn)在的時鐘周期為 600ps,并且由于是單指令周期,指令的執(zhí)行必須執(zhí)行完第一條之后才能執(zhí)行第二條,因此,執(zhí)行完三條指令的時間是 1800 ps。
我們接下來看有流水線技術(shù)后,指令的執(zhí)行時間是多少,為了使得圖更加直觀,這里采用6級流水線,時鐘周期定為 100 ps,執(zhí)行示意圖如下:
通過上圖可以看到流水線技術(shù)的引入使得指令的運行不必等待上一條指令完全執(zhí)行完才執(zhí)行下一條指令,從花費的時間上看 6 級流水線執(zhí)行三條指令花費了 800 ps,而單指令周期處理器卻花費了 1800 ps,可見差距是巨大的。
嵌入式處理器流水線
上述便是關(guān)于單指令周期和流水線的大致內(nèi)容,那在嵌入式中常用的處理器又是怎么一回事呢,我們拿我們經(jīng)常接觸的 ARM Cortex M3 的處理器來說,下圖是筆者在權(quán)威指南中看到的一張圖:
從圖中我們可以看到,Cortex-M3處理器是三級流水線,在指令的運行過程中,處理器將其分為 取指 -> 譯碼 -> 執(zhí)行 三個步驟。而我們常見的 51 單片機在運行時是沒有流水線的,也可以理解為單流水線。
總結(jié)
上述就是關(guān)于流水線技術(shù)和單指令周期的相關(guān)內(nèi)容,當然這只是很小的一部分,真實的處理器上的流水線遠遠不止如此,還會涉及到其他的處理,比如分支預測,亂序執(zhí)行等等,詳細系統(tǒng)的知識還得學習計算機組成原理的相關(guān)內(nèi)容,這次的分享就到這里啦~
您的在看是最我最大的鼓勵,您的建議是對我最大的提升,歡迎點擊下方圖片進入小程序進行評論
免責聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!