在前面文章中,我們交代了計算平臺相關(guān)的一些基本概念以及為什么以GPU為代表的專門計算平臺能夠取代CPU成為大規(guī)模并行計算的主要力量。在接下來的文章中,我們會近距離從軟硬件協(xié)同角度討論GPU計算如何開展。跟先前的文章類似,筆者會采用自上而下,從抽象到具體的方式來論述。希望讀者不只是對GPU計算能有所理解,而且能夠從中了解可以遷移到其它計算平臺的知識,此是筆者之愿景,能否實現(xiàn)一二,還懇請各位看官不斷反饋指正,歡迎大家在后臺留言交流。在本文中,我們首先介紹下GPU及其分類,并簡單回顧下GPU繪制流水線的運作,最后又如何演化為通用計算平臺。
一,什么是GPU及其分類
按維基百科定義,GPU(Graphics Processing Unit,圖形處理器)是一種專門在個人電腦、工作站、游戲機和一些移動設(shè)備(如平板電腦、智能手機等)上運行繪圖運算工作的微處理器。為了以后討論方便,這里先給市面的GPU按配置大致做個分類,分類之間界限比較模糊,不一定完全準確。
獨立GPU(Discrete GPU),或者獨立顯卡。是指GPU通過PCI Express或者早期的AGP、PCI等擴展接口與主板連接。所謂的“獨立”即是指顯卡內(nèi)的RAM只會被該GPU專用,而不是指顯卡是否可從主板上移除。由于尺寸和重量的限制,供筆記本電腦使用的獨立GPU通常會通過非標(biāo)準的接口作連接,然而由于邏輯接口相同,這些接口仍會被視為PCIE,即使在物理上它們是不可與其他顯卡互換。一些專門的GPU互聯(lián)技術(shù),如NVIDIA的SLI、NVLink和AMD的CrossFire等允許多個獨立GPU協(xié)同工作,可顯著增強設(shè)備的圖形處理能力。獨立GPU價格高,體積大,功耗高,但性能更強勁,而且因為自帶顯存,消耗的系統(tǒng)資源也更少。
集成GPU(Integrated GPU), 或者集成顯卡。是集成在主板或CPU上的GPU,運行時會占用部分的系統(tǒng)內(nèi)存,相比起使用獨立顯卡的方案,這種方案較為便宜,但性能也相對較低。從2009年開始,集成GPU已經(jīng)從主板移至CPU了,Intel將之稱為HD Graphics(核芯顯卡),AMD也推出了集成了CPU和GPU的APU。將GPU集成至處理器的好處是可以降低功耗,提升性能。隨著技術(shù)的成熟,目前的集成GPU已經(jīng)足夠應(yīng)付基本3D的需求,不過由于仍然依賴主板本身的RAM,相比獨立顯卡,訪存帶寬始終是個不小的限制。
移動GPU(Mobile GPU)。在移動設(shè)備領(lǐng)域,隨著手機以及平板電腦等設(shè)備對圖形處理能力的需求越來越高,GPU也成為移動處理器(SoC)的標(biāo)配,高通、Imagination和ARM等等都在這個領(lǐng)域大顯身手。我們在以前的文章提到過,蘋果拋棄Imagination的PowerVR IP,在新近的產(chǎn)品采用自研GPU,也成為一股不可忽視的力量。因為移動設(shè)備散熱和電
池供電的限制,功耗是GPU設(shè)計首要考慮的問題,所以移動GPU相比其它GPU架構(gòu)方面會有不小差異。
以后談到GPU計算的時候,我們主要還是以高性能為訴求。所以如果上下文沒有特別說明,我們一般都是針對獨立GPU。
二,GPU繪制流水線
在這節(jié)我們會簡單的介紹GPU的繪制流水線(Rendering Pipeline),GPU就是為圖形繪制加速而生,知道它的來龍去脈,有助于我們理解在其基礎(chǔ)之上衍生的GPGPU。GPU繪制的過程,類似我們生活中拍照和寫生,是有關(guān)如何把三維空間的場景在二維的屏幕上能盡量真實的呈現(xiàn)出來。我們以寫生來做譬喻,針對特定場景輸入,擇一視點,取景構(gòu)圖,按照透視比例通過點線面勾勒出物體的邊界和輪廓,確定明暗色調(diào),注意遠近關(guān)系多層次描繪。
與采用畫筆、相機等工具不同,3D圖形程序通過調(diào)用OpenGL(ES)、Direct3D或者Vulcan API的接口函數(shù)來同GPU硬件交互。為方便論述又不失代表性,下圖是一個相對目前GPU簡化的繪制管線,基本上相當(dāng)于OpenGL(ES) 2.0或者Direct3D 9.0的規(guī)格,繪制管線主要有以下步驟構(gòu)成。值得注意的是,管線分為可編程單元以及固定功能(fixed function)單元,后者優(yōu)化處理管線中不容易并行化的工作,顯然各種Shader都在可編程單元執(zhí)行。
頂點數(shù)據(jù)輸入。3D程序需要的三維場景可以通過3ds Max、Maya等專業(yè)軟件來建模,生成的模型可以有成千上萬個三角面片網(wǎng)格構(gòu)成,其中不僅規(guī)定頂點的位置、顏色、紋理坐標(biāo)和法向量等等屬性也包括它們之間的連接信息。模型導(dǎo)入3D程序以后,就可以成為3D程序的頂點數(shù)據(jù)流,頂點數(shù)據(jù)為為后面的Vertex Shader等階段提供待處理的數(shù)據(jù)。
Vertex Shader(頂點著色器)。Vertex Shader的主要功能是對頂點屬性進行變換,包括頂點位置的坐標(biāo)轉(zhuǎn)換,從局部坐標(biāo)統(tǒng)一到世界坐標(biāo)并切換到視點坐標(biāo)以至裁剪坐標(biāo)。以前也在Vertex Shader進行光照顏色計算,但是由于不夠真實,目前一般移到Fragment Shader階段才發(fā)生。Vertex Shader的輸入輸出都是頂點。
Primitive Setup(圖元裝配)和Rasterization(光柵化)。圖元裝配是將變換后的的頂點根據(jù)連接信息組裝成指定的圖元。圖元裝配階段會進行裁剪(clip)和背面剔除(backface culling)相關(guān)的優(yōu)化,可以減少不必要的工作量。另外還需要透視除法(Perspective Division)達到透視效果,然后通過視口變化(Viewport Transformation)最終得到頂點的屏幕坐標(biāo)。在光柵化階段,基本圖元被轉(zhuǎn)換為一組二維的片元(fragment),片元表示將來可以被渲染到屏幕上的像素,它包含有位置,顏色,紋理坐標(biāo)等信息,這些屬性是由圖元的相關(guān)頂點信息進行插值計算得到的。這些片元接著被送到Fragment Shader處理。
Fragment Shader(片元著色器)。片元著色器用來決定屏幕上潛在像素的最終顏色。在這個階段會依據(jù)紋理坐標(biāo)進行紋理采樣、計算光照以及處理陰影等等,是繪制管線產(chǎn)生高級效果所在。
測試合成。測試合成是繪制管線的最后一個步驟。主要測試有裁剪測試(Scissor Test)、模板測試(Stencil Test)以及深度測試(Depth Test),深度測試就是確認進入的片元有沒有被Framebuffer(幀緩存)同樣位置的像素遮擋。通過最終測試的片元會進入合成階段,就是進入的片元和Framebuffer已有的像素進行混合,根據(jù)顏色的Alpha值取代現(xiàn)有像素或混合產(chǎn)生半透明的效果。Alpha表示的是物體的透明度。測試合成階段不是可編程的,但是我們依舊可以通過3D API提供的接口函數(shù)進行動態(tài)配置,并進一步定制測試和混合的方式。
上面的步驟針對接口函數(shù)其中一個繪制命令,而一幀畫面一般需要很多個繪制命令才能完成,等一幀內(nèi)容結(jié)束以后,該Framebuffer就會作為新的Front Buffer交由顯示設(shè)備顯示,而先前顯示的Front Buffer會變成Back Buffer又開始下一幀的繪制之旅。這就是GPU的雙緩存(Double Buffering)策略。在上層應(yīng)用程序可以通過3D API的接口函數(shù)調(diào)用GPU功能,在底層GPU驅(qū)動將這些接口函數(shù)轉(zhuǎn)化為各種GPU私有的命令執(zhí)行,它們可以完成繪制,狀態(tài)寄存器設(shè)置以及同步等任務(wù)。CPU和GPU通過Ring Buffer(環(huán)形緩存)來傳遞和接受這些命令,CPU承擔(dān)Ring Buffer生產(chǎn)者的角色,而GPU扮演消費者的角色,因為Ring Buffer大小有限,CPU和GPU需要同步。如果CPU老是要等GPU,我們說這個程序是GPU Bound,我們可能需要去優(yōu)化Shader程序,減少三角面片數(shù)量來提高性能。相反如果GPU老是要等CPU,我們就認定這個程序是CPU Bound, 應(yīng)用程序可以考慮把一些CPU預(yù)處理移交給GPU解決,比如利用GPU繪制管線支持的Geometry Shader(幾何著色器)和Tessellation Shaders(細分曲面著色器)來生成額外頂點和圖元,而不是等待CPU輸入等等。
三,GPU計算的演進之旅
隨著真實感繪制進一步發(fā)展,對圖形性能要求愈來愈高,GPU發(fā)展出前所未有的浮點計算能力以及可編程性。這種遠超CPU的計算吞吐和內(nèi)存帶寬使得GPU不只是在圖形領(lǐng)域獨領(lǐng)風(fēng)騷,也開始涉足其它非圖形并行計算應(yīng)用。最早通過使用3D API OpenGL或者DirectX接口函數(shù),很多數(shù)據(jù)并行算法被移植到GPU,性能也獲得很好提升,但是這種利用模式面臨不少問題,下面具體看看一步步是如何解決的。
CUDA的發(fā)明。之前的GPGPU實現(xiàn)需要并行算法程序員很熟悉圖形API和GPU硬件,算法輸入輸出需要定義為圖形繪制的元素,比如頂點坐標(biāo),紋理,幀緩存等,而實際算法又必須著用著色程序(Shader Program)來表達,極大增加了通用并行算法在GPU上移植開發(fā)的復(fù)雜度,另外受限圖形API的表達能力,很多并行問題沒辦法有效發(fā)揮GPU的潛力。2006年,Nvidia破天荒地推出CUDA,作為GPU通用計算的軟件平臺和編程模型,它將GPU視為一個數(shù)據(jù)并行計算的設(shè)備,可以對所進行的計算分配和管理。在CUDA框架中,這些計算不像過去那樣必須映射到圖形API,因此對于開發(fā)者來說,基于CUDA的開發(fā)門檻大大降低了。CUDA編程語言基于標(biāo)準的C語言,一般用戶也很容易上手開發(fā)CUDA的應(yīng)用程序。
統(tǒng)一可編程單元。早些時候的GPU繪制管線都是固定功能的,不存在可編程部分。后來出現(xiàn)了可編程的Vertex和Fragment處理,極大地豐富了繪制效果,但是Vetex和Fragment的處理單元還是分離的,很容易造成負載不均衡,性能的伸縮性也不好。伴隨著Direct3D 10(Shader Model 4.0)出現(xiàn),GPU開始用統(tǒng)一的處理單元運行Vertex、Fragment以及Geomerty Shader。對通用并行計算而言,配合CUDA框架,只要增加GPU可編程處理器數(shù)量配置,這種統(tǒng)一處理方式就能夠最大限度地擴展性能,影響非常深遠。
浮點計算的標(biāo)準化。GPU的可編程處理單元是面向浮點運算,但是浮點數(shù)的支持之前幾乎每個GPU廠商都有自己的解決方案,精度、舍入的處理都不一致,導(dǎo)致計算的準確度存在明顯差異。比如繪制管線傾向于把溢出(overflow),下溢(underflow)和非規(guī)格化浮點數(shù)(denorms)截斷為可表示有意義的最大值或者最小值。現(xiàn)在GPU增加了對特殊數(shù)值(Special Values)Infinity和NaN的支持,計算過程的精度和準確度也向IEEE 754標(biāo)準要求靠攏,比如下圖演示的FMA。浮點計算除支持半精度和單精度以外,雙精度的支持也不可或缺。另外除了浮點數(shù),GPU也開始支持各種各樣的整形運算。這些數(shù)據(jù)類型的支持對GPU通用計算的重要意義不言而喻。
隨機存取數(shù)據(jù)。傳統(tǒng)的GPU架構(gòu)只有非常有限的尋址能力,如通過提供紋理坐標(biāo)給紋理處理單元讀取紋理數(shù)據(jù),F(xiàn)ragment Shader把像素最終的顏色值輸出到對應(yīng)的幀緩存位置,這些讀寫過程用戶沒有辦法顯式控制,非常限制通用計算的數(shù)據(jù)交互能力。現(xiàn)在的的GPU增加了額外的存取單元,在指令集中增加統(tǒng)一尋址存取指令,很大程度拓展了GPU通用計算應(yīng)用空間。
存儲支持ECC。隨著制程工藝不斷進步,器件尺寸縮小,DRAM和SRAM的永久性故障(Hard Error)和瞬時間失效(Soft Error)錯誤都會增加,尤其后者在電容儲存電荷量較小的情況下,問題會越來越嚴重。GPU當(dāng)然也不能幸免,從顯存,到多級cache以至寄存器文件(Register File)都暴露在這一風(fēng)險之下。對圖形應(yīng)用來說,這一問題并不需要太多擔(dān)心,人們根本意識不到屏幕上幾百萬個像素中個別顏色值中一位或幾位bit出現(xiàn)了翻轉(zhuǎn),哪怕發(fā)生更嚴重的錯誤,人類的視覺機制都有機會自我補償糾正。但在高性能計算領(lǐng)域,差之毫厘,謬以千里,這些存儲失效的問題都是不能承受之重。所以現(xiàn)在GPU廠商至少會針對HPC產(chǎn)品在整個存儲器層次結(jié)構(gòu)添加ECC(Error Correcting Code)支持,數(shù)據(jù)中心和服務(wù)器的客戶也才敢放心購買使用。
有了以上一些改進和其他措施,終于GPU作為通用計算平臺慢慢脫離原始階段,開始成熟起來,成為大規(guī)模并行計算市場的主力軍。
責(zé)任編輯:lq6
-
gpu
+關(guān)注
關(guān)注
28文章
4764瀏覽量
129172 -
計算平臺
+關(guān)注
關(guān)注
0文章
53瀏覽量
9674
原文標(biāo)題:近距離看GPU計算
文章出處:【微信號:LinuxDev,微信公眾號:Linux閱碼場】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論