HPC高效能運算知識: GPU的工作原理(含視訊)

架構師技術聯盟發表於2018-04-18

640?wx_fmt=png&wxfrom=5&wx_lazy=1


640?wx_fmt=gif&wxfrom=5&wx_lazy=1

      在GPU出現以前,顯示卡和CPU的關係有點像“主僕”,簡單地說這時的顯示卡就是畫筆,根據各種有CPU發出的指令和資料進行著色、材質的填充、渲染、輸出等。


      較早的娛樂用的3D顯示卡又稱“3D加速卡”,由於大部分座標處理的工作及光影特效需要由CPU親自處理,佔用了CPU太多的運算時間,從而造成整體畫面不能非常流暢地表現出來。


      例如,渲染一個複雜的三維場景,需要在一秒內處理幾千萬個三角形頂點和光柵化幾十億的畫素。早期的3D遊戲,顯示卡只是為螢幕上顯示畫素提供一個快取,所有的圖形處理都是由CPU單獨完成。圖形渲染適合並行處理,擅長於執行序列工作的CPU實際上難以勝任這項任務。所以,那時在PC上實時生成的三維影象都很粗糙。不過在某種意義上,當時的圖形繪製倒是完全可程式設計的,只是由CPU來擔綱此項重任,速度上實在是達不到要求。


      隨著時間的推移,CPU進行各種光影運算的速度變得越來越無法滿足遊戲開發商的要求,更多多邊形以及特效的應用榨乾了幾乎所有的CPU效能,矛盾產生了。


GPU的誕生


      NVIDIA公司在1999年8月31日釋出GeForce 256圖形處理晶片時首先提出GPU的概念


      GPU之所以被稱為圖形處理器,最主要的原因是因為它可以進行幾乎全部與計算機圖形有關的資料運算,而這些在過去是CPU的專利。


      目前,計算機圖形學正處於前所未有的發展時期。近年來,GPU技術以令人驚異的速度在發展。渲染速率每6個月就翻一番。效能多年來翻番了十倍百倍,也就是(2的10次方比2)提高了上千倍!與此同時,不僅效能得到了提高,計算質量和圖形程式設計的靈活性也逐漸得以改善。


      以前,PC和計算機工作站只有圖形加速器,沒有圖形處理器(GPU),而圖形加速器只能簡單的加速圖形渲染。而GPU取代了圖形加速器之後,我們就應該摒棄圖形加速器的舊觀念。


GPU的結構


      GPU全稱是Graphic Processing Unit(圖形處理器),其最大的作用就是進行各種繪製計算機圖形所需的運算,包括頂點設定、光影、畫素操作等。GPU實際上是一組圖形函式的集合,而這些函式由硬體實現。以前,這些工作都是有CPU配合特定軟體進行的,GPU從某種意義上講就是為了在圖形處理過程中充當主角而出現的。


      一個簡單的GPU結構示意圖包含一塊標準的GPU。主要包括2D Engine、3D Engine、VideoProcessing Engine、FSAA Engine、視訊記憶體管理單元等。其中,3D運算中起決定作用的是3DEngine,這是現代3D顯示卡的靈魂,也是區別GPU等級的重要標誌。


      3DEngine在各公司的產品中都是宣傳攻勢的重點照顧物件,名字一個比一個響,像NVIDIA的nFjnjtFX系列、CineFX系列,AMD的SmoothVision系列。一個3DEngine通常包含著T&L單元、Vertex Proeessing Engine、SetupEngine、PiexlShader等部分。


GPU的工作原理


      現在讓我們來看看第二代GPU是如何完整處理一個畫面的吧!首先,來自CPU的各種物理引數進入GPU,Vertex shader將對頂點資料進行基本的判斷。如果沒有需要處理的Vertex 效果,則頂點資料直接進入T&L Unit 進行傳統的T&L操作以節約時間提高效率。


 GPU中資料的處理流程


      如果需要處理各種Vertex 效果,則Vertex shader將先對各種Vertex Programs的指令進行運算,一般的Vertex Programs中往往包含了過去轉換、剪下、光照運算等所需要實現的效果,故經由Vertex shader處理的效果一般不需要再進行T&L操作。另外,當遇到涉及到曲面鑲嵌(把曲面,比如弓形轉換成為多邊形或三角形)的場合時。CPU可以直接將資料交給Vertex shader進行處理。


      另外,在DireetX的Transform過程中,Vertex shader可以完成Z值的剔除,也就是Back Face Culling――陰面隱去。這就意味粉除了視野以外的頂點,視野內坡前面項點遮住的頂點也會被一併剪除,這大大減輕了需要進行操作的頂點數目。


      接下來,經由VertexShader處理完成的各種資料將流入Setup Engine,在這裡,運算單元將進行三角形的設定工作,這是整個繪圖過程中最重要的一個步驟,Setup Engine甚至直接影響著一塊GPU的執行效能。三角形的設定過程是由一個個多邊形組成的,或者是用更好的三角形代替原來的三角形。在三維圖象中可能會有些三角形被它前面的三角形擋住,但是在這個階段3D晶片還不知道哪些三角形會被擋住,所以三角形建立單元接收到是一個個由3個頂點組成的完整三角形。三角形的每個角(或頂點)都有對應的X軸、Y軸、Z軸座標值,這些座標值確定了它們在3D景物中的位置。同時,三角形的設定也確定了畫素填充的範圍。至此,VertexShader的工作就完成了。


      過去或第一代,設定好的三角形本來應該帶著各自所有的引數進入畫素流水線內進行紋理填充和演染,但現在則不同,在填充之前我們還播要進行Piexl Shader的操作


      其實,PiexIShader並非獨立存在的,它位於紋理填充單元之後,資料流入像紊流水線後先進入紋理填充單元進行紋理填充,然後便是PiexlShader單元,經由PiexlShader單元進行各種處理運算之後再進入畫素填充單元進行具體的粉色,再經由霧化等操作後,一個完整的畫面就算完成了。

      值得注意的是,第二代GPU中普遮引入了獨立的顯示資料管理機制,它們位於VertexShader、SetuPEngine以及畫素流水線之間,負資資料更有效率地傳輸和組合、各種無效值的剔除、資料的壓縮以及暫存器的管理等工作,這個單元的出現對整個GPU工作效率的保證起到了至關重要的作用。


      簡而言之,GPU的圖形(處理)流水線完成如下的工作(並不一定是按照如下順序):


  • 頂點處理: 這階段GPU讀取描述3D圖形外觀的頂點資料並根據頂點資料確定3D圖形的形狀及位置關係,建立起3D圖形的骨架。在支援DX系列規格的GPU中,這些工作由硬體實現的Vertex Shader(定點著色器)完成。

  • 光柵化計算: 顯示器實際顯示的影象是由畫素組成的,我們需要將上面生成的圖形上的點和線通過一定的演算法轉換到相應的畫素點。把一個向量圖形轉換為一系列畫素點的過程就稱為光柵化。例如,一條數學表示的斜線段,最終被轉化成階梯狀的連續畫素點。

  • 紋理帖圖: 頂點單元生成的多邊形只構成了3D物體的輪廓,而紋理對映(texture mapping)工作完成對多變形表面的帖圖,通俗的說,就是將多邊形的表面貼上相應的圖片,從而生成“真實”的圖形。

  • 畫素處理: 這階段(在對每個畫素進行光柵化處理期間)GPU完成對畫素的計算和處理,從而確定每個畫素的最終屬性。在支援DX8和DX9規格的GPU中,這些工作由硬體實現的Pixel Shader(畫素著色器)完成。

  • 最終輸出: 由ROP(光柵化引擎)最終完成畫素的輸出,1幀渲染完畢後,被送到視訊記憶體幀緩衝區。


      總結:GPU的工作通俗的來說就是完成3D圖形的生成,將圖形對映到相應的畫素點上,對每個畫素進行計算確定最終顏色並完成輸出。


640?wx_fmt=jpeg

GPU流程示意圖

 

      如今的顯示卡圖形,單從圖象的生成來說大概需要Homogeneous coordinates(齊次座標)、Shading models(陰影建模)、Z Buffering(Z緩衝)、Texture Mapping(材質貼圖)四個步驟。


      在這些步驟中,顯示部分(GPU)只負責完成第三、四步,而前兩個步驟主要是依靠 CPU 來完成。而且,這還僅僅只是3D圖象的生成,還沒有包括圖形中複雜的AI運算。場景切換運算等等。無疑,這些元素還需要CPU去完成。

 

CPU與GPU的資料處理關係


      接下來,讓我們簡單的看一下CPU和GPU之間的資料是如何互動的。首先從硬碟中讀取模型, CPU分類後將多邊形資訊交給GPU,GPU再時時處理成螢幕上可見的多邊形,但是沒有紋理只有線框。


      模型出來後,GPU將模型資料放進視訊記憶體,顯示卡同時也為模型貼材質給模型上顏色。CPU相應從視訊記憶體中獲取多邊形的資訊。然後CPU計算光照後產生的影子的輪廓。等CPU計算出後,顯示卡的工作又有了,那就是為影子中填充深的顏色。


傳統GPU指令的執行


      傳統的GPU基於SIMD的架構,SIMD即Single Instruction Multiple Data,單指令多資料。其實這很好理解,傳統的VS和PS中的ALU(算術邏輯單元,通常每個VS或PS中都會有一個ALU,但這不是一定)都能夠在一個週期內(即同時)完成對向量4個通道的運算。比如執行一條4D指令,PS或VS中的ALU對指令對應定點和畫素的4個屬性資料都進行了相應的計算。這便是SIMD的由來。這種ALU我們暫且稱它為4DALU。 


      需要注意的是,4D SIMD架構雖然很適合處理4D指令,但遇到1D指令的時候效率便會降為原來的1/4。此時ALU 3/4的資源都被閒置。為了提高PS VS執行1D 2D 3D指令時的資源利用率,DirectX9時代的GPU通常採用1D+3D或2D+2DALU,這便是Co-issue技術。這種ALU對4D指令的計算時仍然效能與傳統的ALU相同,但當遇到1D 2D 3D指令時效率則會高不少,對於傳統的4D ALU,顯然需要兩個週期才能完成,第一個週期ALU利用率75% ,第二個週期利用率25%。而對於1D+3D的ALU,這兩條指令可以融合為一條4D指令,因而只需要一個週期便可以完成,ALU利用率100%。


      當然,即使採用Co-issue,ALU利用率也不可能總達到100%,這涉及到指令並行的相關性等問題,而且,更直觀的,上述兩條指令顯然不能被2D+2DALU一週期完成,而且同樣,兩條2D指令也不能被1D+3DALU一週期完成。傳統GPU在對非4D指令的處理顯然不是很靈活。


640?wx_fmt=jpeg


      另外,CPU中大部分電晶體主要用於構建控制電路(象分支預測等)和Cache,只有少部分的電晶體來完成實際的運算工作。而GPU的控制相對簡單,而且對Cache的需求小,所以大部分電晶體可以組成各類專用電路、多條流水線,使得GPU的計算速度有了突破性的飛躍,擁有了驚人的處理浮點運算的能力。現在CPU的技術進步正在慢於摩爾定律,而GPU(視訊卡上的圖形處理器)的執行速度已超過摩爾定律,每6個月其效能加倍。


<知識擴充套件閱讀>



溫馨提示:
請搜尋“ICT_Architect”“掃一掃”二維碼關注公眾號,點選原文連結獲取更多HPC技術資料

640?wx_fmt=png

求知若渴, 虛心若愚—Stay hungry, Stay foolish

640?wx_fmt=gif

相關文章