深刻淺出計算機組成原理學習筆記:第二十講

1、引子

前面咱們用了三講,用一個個的電路組合,製做出了一個完整功能的CPU。這裏面一會兒給你引入了三個「週期」的概念,分別是指令週期、機器週期(或者CPU週期)以及時鐘週期。程序員

你可能會有點摸不着頭腦了,爲何小小一個CPU,有那麼多的週期(Cycle)呢?咱們在專欄一開始,不是把CPU的性能定義得很是清楚了嗎?咱們說程序的性能,是由三個因素相乘來衡量的,
咱們還專門說過「指令數×CPI×時鐘週期」這個公式。這裏面和週期相關的只有一個時鐘週期,也就是咱們CPU的主頻倒數。當時講的時候咱們說,一個CPU的時鐘週期能夠認爲是能夠完成一條最簡單的計算機指令的時間。後端

那麼,爲何咱們在構造CPU的時候,一會兒出來了那麼多個週期呢?這一講,我就來爲你說道說道,帶你更深刻地看看現代CPU是怎麼一回事兒。性能

2、願得一心人,白首不相離:單指令週期處理器

一、爲何要把把時鐘週期和執行時間最長的那個指令設成同樣

學過前面三講,你如今應該知道,一條CPU指令的執行,是由「取得指令(Fetch)-指令譯碼(Decode)-執行指令(Execute) 」這樣三個步驟組成的。這個執行過程,至少須要花費一個時鐘週期。
由於在取指令的時候,咱們須要經過時鐘週期的信號,來決定計數器的自增。spa

那麼,很天然地,咱們但願能確保讓這樣一整條指令的執行,在一個時鐘週期內完成。這樣,咱們一個時鐘週期能夠執行一條指令,CPI也就是1,看起來就比執行一條指令須要多個時鐘週期性能要好。採用這種設計思路的處理器,就叫做單指令週期處理器(Single Cycle Processor),也就是在一個時鐘週期內,處理器正好能處理一條指令。設計

不過,咱們的時鐘週期是固定的,可是指令的電路複雜程度是不一樣的,因此實際一條指令執行的時間是不一樣的。在第13講和第14講講加法器和乘法器電路的時候,我給你看過,
隨着門電路層數的增長,因爲門延遲的存在,位數多、計算複雜的指令須要的執行時間會更長。code

不一樣指令的執行時間不一樣,可是咱們須要讓全部指令都在一個時鐘週期內完成,那就只好把時鐘週期和執行時間最長的那個指令設成同樣。這就比如學校體育課1000米考試,
咱們要給這場考試預留的時間,確定得和跑得最慢的那個同窗同樣。由於就算其餘同窗先跑完,也要等最慢的同窗跑完間,咱們才能進行下一項活動。blog

 

 

二、爲何單指令週期處理器變成了執行一條最複雜的指令的時間呢?

因此,在單指令週期處理器裏面,不管是執行一條用不到ALU的無條件跳轉指令,仍是一條計算起來電路特別複雜的浮點數乘法運算,咱們都等要等滿一個時鐘週期。
在這個狀況下,雖然CPI可以保持在1,可是咱們的時鐘頻率卻無法過高。由於過高的話,有些複雜指令沒有辦法在一個時鐘週期內運行完成。那麼在下一個時鐘週期到來,開始執行下一條指令的時候,前一條指令的執行結果可能尚未寫入到寄存器裏面。那下一條指令讀取的數據就是不許確的,就會出現錯誤。ip

到這裏你會發現,這和咱們以前第3講和第4講講時鐘頻率時候的說法不太同樣。當時咱們說,一個CPU時鐘週期,能夠認爲是完成一條簡單指令的時間。爲何到了這裏,
單指令週期處理器,反而變成了執行一條最複雜的指令的時間呢?內存

這是由於,不管是PC上使用的Intel CPU,仍是手機上使用的ARM CPU,都不是單指令週期處理器,而是採用了一種叫做 指令流水線(Instruction Pipeline)的技術。開發

3、迫不得已花落去,似曾相識燕歸來:現代處理器的流水線設計

一、開發手機App上的功能和指令執行過程思路是如何同樣?

開發手機App上的功能

指令執行過程也是同樣的

二、共同協做完成任務和CPU指令執行過程思路是如何同樣?

共同協做完成任務

CPU指令執行過程

三、時鐘週期設置和後端程序員工做思路是如何同樣?

時鐘週期設置

後端程序員

 

 

若是咱們把一個指令拆分紅「取指令-指令譯碼-執行指令」這樣三個部分,那這就是一個三級的流水線。若是咱們進一步把「執行指令」拆分紅「ALU計算(指令執行)-內存訪問-數據寫回」,
那麼它就會變成一個五級的流水線。

五級的流水線,就表示咱們在同一個時鐘週期裏面,同時運行五條指令的不一樣階段。這個時候,雖然執行一條指令的時鐘週期變成了5,可是咱們能夠把CPU的主頻提得更高了。
 咱們不須要確保最複雜的那條指令在時鐘週期裏面執行完成,而只要保障一個最複雜的流水線級的操做,在一個時鐘週期內完成就行了。

若是某一個操做步驟的時間太長,咱們就能夠考慮把這個步驟,拆分紅更多的步驟,讓全部步驟須要執行的時間儘可能都差很少長。這樣,也就能夠解決咱們在單指令週期處理器中遇到的,
性能瓶頸來自於最複雜的指令的問題。像咱們現代的ARM或者Intel的CPU,流水線級數都已經到了14級。

雖然咱們不能經過流水線,來減小單條指令執行的「延時」這個性能指標,可是,經過同時在執行多條指令的不一樣階段,咱們提高了CPU的「吞吐率」。在外部看來,咱們的CPU好像是「一心多用」,
在同一時間,

同時執行5條不一樣指令的不一樣階段。在CPU內部,其實它就像生產線同樣,不一樣分工的組件不斷處理上游傳遞下來的內容,而不須要等待單件商品生產完成以後,再啓動下一件商品的生產過程。

4、超長流水線的性能瓶頸

一、增長流水線深度,實際上是有性能成本的

既然流水線能夠增長咱們的吞吐率,你可能要問了,爲何咱們不把流水線級數作得更深呢?爲何不作成20級,乃至40級呢?這個其實有不少緣由,我在以後幾講裏面會詳細講解。
這裏,我先講一個最基本的緣由,就是增長流水線深度,實際上是有性能成本的。

咱們用來同步時鐘週期的,再也不是指令級別的,而是流水線階段級別的。每一級流水線對應的輸出,都要放到流水線寄存器(Pipeline Register)裏面,而後在下一個時鐘週期,交給下一個流水線級去處理。因此,每增長一級的流水線,就要多一級寫入到流水線寄存器的操做。雖然流水線寄存器很是快,好比只有20皮秒

可是,若是咱們不斷加深流水線,這些操做佔整個指令的執行時間的比例就會不斷增長。最後,咱們的性能瓶頸就會出如今這些overhead上。若是咱們指令的執行有3納秒,也就是3000皮秒。
咱們須要20級的流水線,那流水線寄存器的寫入就須要花費400皮秒,佔了超過10%。若是咱們須要50級流水線,就要多花費1納秒在流水線寄存器上,佔到25%。這也就意味着,單純地增長流水線級數,不只不能提高性能,反而會有更多的overhead的開銷。因此,設計合理的流水線級數也是現代CPU中很是重要的一點。

5、總結延伸

講到這裏,相信你已經可以理解,爲何咱們的CPU須要流水線設計了,也能把每個流水線階段在幹什麼,和上一講的整個CPU的數據通路的鏈接過程對上了。

能夠看到,爲了可以不浪費CPU的性能,咱們經過把指令的執行過程,切分紅一個一個流水線級,來提高CPU的吞吐率。而咱們自己的CPU的設計,又是由一個個獨立的組合邏輯電路串接起來造成的,自然可以適合這樣採用流水線「專業分工」的工做方式。

由於每一級的overhead,一味地增長流水線深度,並不能無限地提升性能。一樣地,由於指令的執行再也不是順序地一條條執行,而是在上一條執行到一半的時候,下一條就已經啓動了,因此也給咱們的程序帶來了不少挑戰。這些挑戰和對應的解決方案,就要請你堅持關注後面的幾講,咱們一塊兒來揭開答案了

相關文章
相關標籤/搜索