跟濤哥一起學嵌入式 31:深入淺出CPU流水線工作原理

現在的CPU處理器一般都是超流水線工作,動不動就是10級以上流水線,超高主頻,這兩者之間有什麼關係呢?今天就跟大家科普下CPU流水線的工作原理,以及他們之間的關係。

說到流水線,很多人會想到富士康;說到富士康,很多人會想到張全蛋。作爲富士康 3 號流水線資深質檢員,下面就請張全蛋給大家科普下什麼是流水線,大家鼓掌歡迎。

 

Micheal Jack 眼中的流水線

大家好,我是張全蛋,英文名叫Micheal Jack,法文名叫霍雷呆-傑Q賴,大家也可以叫我查理。作爲iPhone 手機 3 號流水線的資深質檢員,我很忙的,每分鐘都是幾百萬的生意。像我們富士康這樣的transnational enterprise,經常會和不同國家的客戶說一些技術上的meeting啊、下班陪他們message啊,都需要英文的。像我們廠裏不會說英語的啊,都會被經理 fire 掉的。在我們廠裏,流水線叫法太 low了,我們都叫 pipeline,一條pipeline,每個人分工不同,從手機原材料到成品iPhone ,只需要短短幾分鐘。嵌入式C語言自我修養

 

 

查理很忙,介紹到這裏就走了,接下來我們繼續瞭解下什麼叫流水線。

流水線是工業大生產下的產物。在農業社會做一部手機,需要的是工匠、手藝人,就像故宮裏製作鐘錶的那些匠人一樣,是需要拜師學藝、慢慢學習的:從手機組裝、質檢、貼膜、包裝都是一個人,什麼都要學。手藝人慢工出細活,但成本很高,到了工業化社會就不一樣了:大家分工合作,將做手機這個複雜過程拆分爲多個簡單步驟,每個人負責一個步驟,經過刻意(機械)練習和培訓,就可以很快上手。每個人都做自己最擅長的,可以大大提高工作效率。

如果每個人都單獨做一部手機,焊接電路、組裝成品這一步驟一般人需要8分鐘,測試檢驗一般需要4分鐘,貼膜包裝成盒一般需要4分鐘,總共需要16分鐘。每16分鐘,如果有3個工人的話,一共可以生產3部手機。一個新員工從進廠開始,要培訓學習三個月才能掌握所有的技能,才能上崗。如果引入生產流水線就不一樣了,每個人只負責一個工序,比如趙鐵柱只負責焊接電路、組裝手機,李小花只負責貼膜,進廠培訓3天就可以快速上手了,對工人的技能要求大大降低!而且隨着時間積累,每個人對自己所負責的工序越來越熟練,每道工序需要的時間大大減少:趙鐵柱焊接電路越來越順手,花費時間從原來的8分鐘縮減爲4分鐘;張全蛋的質量檢驗練得如火純情,整個流程做完只需要2分鐘;李小花的貼膜技術也越來越溜了,從貼膜到包裝2分鐘搞定。每16分鐘,趙鐵柱可以焊接4塊電路板 ,整個流水線可以生產出4部手機,產能整整提升了33.33%!老闆高興,趙鐵柱高興,張全蛋和李小花更高興,因爲每做2分鐘,他們還可以休息2分鐘,刷刷微博滑個抖音,豈不樂哉!

看到這裏可能有人擡槓了:你這麼算是不對的,每道工序所用的時間都變爲原來的一半,怎麼可能做得到?其實要做到不難的,只要工序拆解得合理,容易上手,再加上足夠時間的機械重複,很多人都可以做得到。只要獎金髮到位,蛋糕店裏的小姐姐夾蛋糕的速度比你眨眼的速度都快,銀行櫃檯的小李數鈔票的速度比點鈔機都快,買單時飯店前臺的小妹摁計算器的速度比你掏錢的速度都快。

 

流水線工作原理

一條指令的執行一般要經過:取指令、翻譯指令、執行指令三個基本流程。CPU內部的電路分爲不同的單元:取指單元、譯碼單元、執行單元等,指令的執行也是按照流水線工序一步一步執行的。我們假設每一個步驟執行時間都是一個時鐘週期,那麼一條指令執行需要3個時鐘週期。

 

 

CPU 執行指令的3個時鐘週期裏,取指單元只在第一個時鐘週期裏工作,其餘兩個時鐘週期都處於空閒狀態,其它兩個執行單元也是如此,效率太低了,消費者無法接受,老闆也不能接受。解決方法就是引入流水線,讓流水線每一顆螺絲釘都馬不停蹄地運轉起來,最好一刻也不要停。

 

 

引入流水線工作模式後可以看到,除了剛開始第一個時鐘週期大家還可以偷懶外,其餘的時間都不能閒着:從第二個時鐘週期開始,當譯碼單元在翻譯指令1時,取指單元也不能閒着,要接着去取指令2。同樣如此,從第三個時鐘週期開始,當執行單元執行指令1時,譯碼單元也不能閒着,要接着去翻譯指令2,而取指單元要去取指令3。從第四個時鐘週期開始,每個電路單元都會進入滿荷負載工作狀態,像富士康工廠裏的流水線一樣,源源不斷地執行一條條指令。

引入流水線後,雖然每一條指令執行流程不變,還是需要3個時鐘週期,但是從整條流水線的輸出看來,差不多平均每個時鐘週期就能執行一條指令。原來執行一條指令需要3個時鐘週期,現在平均只需要1個時鐘週期,CPU 性能提升了不少。

流水線的本質其實就是拿空間資源換時間。將每條指令分解爲多步,指令的每一步都有獨立的電路來執行,並讓不同指令的各步操作重疊,從而實現幾條指令並行處理,從而加快程序的運行。

CPU內部的流水線如此,富士康工廠裏的iPhone流水線也是如此,通過不斷往流水線增加人手來提高流水線的生產效率,也就是吞吐率。

 

超流水線技術

想知道什麼是超流水線,讓我們再回到富士康。

在富士康 3 號 iPhone 流水生產線上,因爲趙鐵柱工作效率不高,焊接組裝一步手機需要 4 分鐘,導致生產一部iPhone手機也得需要 4 分鐘,從而拖累了整條生產線的生產效率。老闆很生氣,後果很嚴重,趙鐵柱沒幹到一個月就被 fire 掉了。後面幾個月,陸陸續續來了不少人:小黑、皮褲哥、紅姐,都想試試這份工作,可惜幹得還不如趙鐵柱,挑戰電子廠失敗,早已提桶跑路。

老闆招不到人,感覺又錯怪了趙鐵柱,於是決定升級生產線,並承諾加薪重新召回了趙鐵柱。

 

 

老闆找出了生產線的瓶頸:每道工序都是需要2分鐘,只有趙鐵柱這道工序耗時4分鐘,老闆錯怪了這鐵柱,這不是趙鐵柱的原因,是因爲這道工序太複雜。於是把這道工序進行了拆解爲2道工序:焊接電路板和組裝手機。焊接電路仍由趙鐵柱負責,把電路板、顯示屏、手機外殼組裝成手機這道工序則由新招員工王建國負責。生產流水線優化後,趙鐵柱焊接電路只需要2分鐘,王建國組裝也只需要 2 分鐘,生產每部 iPhone 的時間由原來的 4 分鐘縮減爲 2 分鐘,生產流水線的瓶頸解決了!

跟富士康流水線類似,優化CPU流水線也是提升CPU性能的有效手段。流水生產線存在木桶短板效應,我們只需要找出CPU流水線中的性能瓶頸,即耗時最長的那道工序,然後再進行細分、優化爲更多的工序就可以了。每一道工序我們稱爲流水線的一級,流水線越深,每一道流水電路單元的執行時間就會變得越小,我們處理器的時鐘週期就可以更短,從而可以通過提升CPU主頻來提升CPU性能、提高工作效率。

在富士康流水生產線中,每道工序的最長耗時時間決定了整條生產線的吞吐率。在CPU內部也是如此,每個流水單元的執行時間(即時間延遲)決定了CPU流水線的性能。CPU流水線中的每一道電路單元由組合邏輯電路和寄存器組成,邏輯單路用來執行本道工序的邏輯運算,寄存器用來保存結果,並作爲下一道工序的輸入。

 

 

流水生產線是通過減少每一道工序的耗費時間來提升整條流水線效率的。在CPU內部也是如此,CPU內部的數字電路是靠時鐘驅動來工作的,既然每條指令的執行時鐘週期數不變,即執行每條指令需要3個時鐘週期,但是我們可以通過縮短時鐘週期的方法來提升效率,即減少每條指令所耗費的時間。減少時鐘週期,也就是提升CPU主頻,一個關鍵的制約因素就是CPU內部每一個執行單元的耗費時間。雖然說電信號在電路中的傳播時間很快,可以接近光速,但是經過成千上萬的晶體管,不停地信號翻轉,還是會帶來一定的時間延遲,這個時間延遲我們可以看做這道工作的執行時間。以上圖爲例,如果每個執行單元的延遲是 1.5 納秒,那麼你的時鐘週期至少也得2納秒以上,否則電路就會工作異常。如果驅動CPU工作的時鐘週期是 2 納秒,CPU的主頻就是 500 MHz。現在的CPU流水線深度可以做到10級以上,流水線的每一級時間延遲可以做到皮秒級別,驅動CPU工作的時鐘週期可以做到更短,因此可以把CPU的主頻飆到 5 GHz 以上。

我們把5級以上的流水線稱爲超流水線結構。高性能的處理器,爲了提升CPU主頻,一般都會採用這種超流水線結構。Intel的 i7 處理器有16級流水線,AMD的速龍64系列CPU流水線爲20級。史上具有最長流水線的是Intel的第三代奔騰四處理器,有31級的流水線。

想要提升CPU的主頻,根本在於減少流水線中每一級流水的執行時間,消除木桶的短板效應,才能提升流水線的整體性能。解決方法有三個:一是優化流水線中各級流水線的性能,受限於當前集成電路的設計水平,這一步最難;二是依靠集成電路的製造工藝,更先進的納米工藝,芯片面積越小,發熱越小,更容易提升主頻;三是不斷地增加流水線,流水線越深,流水線的各級延遲就可以做得越小,更容易提高主頻。

流水線是否越深越好呢?非也。流水線的本質是拿空間換時間,流水線越深,電路就會越複雜,需要更多的組合邏輯電路和寄存器,芯片面積也就越大,功耗也就隨之上升了。拿功耗增長換來性能提升,在PC機和服務器上還行,但對於很多靠電池供電的移動設備的處理器來說就無法接受了,CPU設計人員需要在性能和功耗之間做一個很好的平衡。

流水線越深,就越能提升性能嗎?也不一定。流水線是靠指令的並行來提升性能的,第一條指令還沒有執行完,下面的第二條指令就開始取指、譯碼了。執行的程序指令如果是順序結構,沒有中斷或跳轉,流水線確實可以提高執行效率。但是當程序指令中存在跳轉、分支結構時,下面預取的指令可能就要全部丟掉了,需要到要跳轉的地方重新取指令執行。

BEQ R1, R2, here
ADD R2, R1, R0
ADD R5, R4, R3
...
here:
SUB R2, R1, R0
SUB R5, R4, R3
...

流水線越深,一旦預取指令失敗,浪費和損失就會越嚴重,因爲流水線中預取的幾十條指令可能都要丟棄掉,流水線發生了停頓,無法按照預期繼續執行,這種情況我們一般稱之爲流水線冒險(hazard)。在現在很多超流水線處理器中,爲了避免這種情況出現,會採取各種各樣的方法去避免這種情況,以免影響處理器的性能。--本文摘自《嵌入式C語言自我修養》e的標籤處取SUB指令,流水線才能接着繼續執行。

流水線越深,一旦預取指令失敗,浪費和損失就會越嚴重,因爲流水線中預取的幾十條指令可能都要丟棄掉,流水線發生了停頓,無法按照預期繼續執行,這種情況我們一般稱之爲流水線冒險(hazard)。在現在很多超流水線處理器中,爲了避免這種情況出現,會採取各種各樣的方法去避免這種情況發生,以免影響處理器的性能。--本文摘自《嵌入式C語言自我修養》

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