王 可 杜慧敏 黃虎才 劉世豪 劉 鑫
(西安郵電大學電子工程學院 西安 710121)
隨著半導體工藝、計算機圖形學以及微電子技術的迅速發(fā)展,人們不斷地追求視覺上更加逼真的渲染效果[1~2]。因此對于圖形處理器(Graphics Processing Unit,GPU)的繪制性能和功耗的要求也越來越高。人們需要GPU 以更低的功耗、更加有限的存儲資源和帶寬實現更高性能、更高質量、更低功耗的圖形繪制。相較于PC 端的圖形處理器,嵌入式GPU 由于其電源的局限性,對于其功耗的要求更加苛刻。目前一些國際知名的GPU 廠商像NVIDIA、AMD 已經相繼采用了HBM(high bandwidth memory)或者GDDR(graphic DDR)等關鍵技術,且都不同程度地提升了GPU 的片外存儲器帶寬,但是同用戶持續(xù)增長的需求相比,存儲資源和帶寬的有限性依舊是一個技術難題。如何提高GPU功耗效率已經成為了3D圖形渲染領域的一個熱點問題[3~6]。對于多核處理器實現的GPU 而言,限制其性能和功耗的最主要為運算速度、訪問存儲速度和存儲資源占用的問題。據統計,GPU進行三維圖形繪制需頻繁地訪問外部存儲器,導致訪問片外存儲器耗費的功耗接近芯片總功耗的60%~70%[7~8],成為圖形處理器的主要性能瓶頸[9]。
為了減少對片外存儲的訪問,其中一種方法就是對處理的數據進行壓縮。在圖形處理器流水線上采用壓縮的圖形繪制數據能夠有效減少存儲的訪問量,降低數據的傳輸量。在圖形處理器中,數據壓縮時需要考慮不同的壓縮對象對數據精確性的要求。比如紋理數據,作為只讀數據,壓縮紋理圖像造成的誤差不會對最終繪制出的圖像產生較大的影響,故而紋理壓縮一般都是有損壓縮。但是頂點信息與繪制三角形的數量和類型直接相關,對于產生的誤差十分敏感,需要較高的精確性,因此需要采取無損壓縮方式[10~11]。
在圖形處理器流水線上采用壓縮的圖形繪制數據能夠有效減少存儲的訪問量,降低數據的傳輸量。例如,NVIDIA Tegra 4 移動圖形處理器核的圖形渲染流水線集成了專用存儲訪問管理系統,實現16∶1 的無損深度(depth)壓縮、4∶1 的無損顏色和4∶1 的紋理。NVIDIA TegraX1 的Maxwell 系列GPU核對顏色數據(紋理、顏色緩沖區(qū)和幀緩沖區(qū))應用數據壓縮技術,相比未使用數據壓縮技術的GPU系統,平均節(jié)省60%左右的存儲器帶寬[12~13]。
OpenGL 中的DrawElements的繪制模式需要用戶利用頂點索引數組來指定頂點索引,導致GPU對外存的訪問頻繁。本文提出一種DrawElements模式對頂點索引信息進行無損壓縮的方法,對數據存儲空間做了較大的優(yōu)化,減少了存儲資源的占用。在主機端對用戶指定的頂點索引數組進行數據的無損壓縮,并在圖形處理器內部進行解壓縮處理。這樣的處理方式雖然增加了硬件的復雜性,但是可以大大節(jié)省存儲空間的占用并且不會導致頂點索引數據的準確度降低,在一定程度上提升了整個處理器的性能。
本文對提出的壓縮算法進行了建模并用System Verilog 構建了仿真平臺,對不同測試用例下的頂點索引進行了仿真,統計其壓縮比。由測試結果得出,該方法可以較好地減小存儲資源的占用。
文獻[14~16]對數據壓縮的方式即有損壓縮和無損壓縮做了簡單的概述[14~16]。文獻[17]中針對圖形處理器流水線數據壓縮技術的應用現狀進行了總結和分析。在3D 圖形渲染流水線的多個階段,使用了數據壓縮技術減少了訪問外部存儲器的次數,從而達到提高渲染性能和降低能耗的效果。通過分析GPU 圖形渲染流水線和存儲系統的結構特征,總結了各種緩沖區(qū)對象、紋理數據專用壓縮算法的關鍵特性以及所使用的壓縮算法的特征。最后,分析了當前圖形流水線數據壓縮技術的研究現狀、不足與挑戰(zhàn)[17]。十多年前,Alliez[18]等分析并總結了三維網格壓縮算法特征,一些算法壓縮率較高,但是壓縮操作和解壓縮操作相當復雜,面積開銷大,另外一些算法無法對壓縮數據實現并行解壓縮操作,導致這些算法無法應用于嵌入式移動設備。2005 年,Pur-nomo[19]等提出一種幾何緩沖區(qū)的壓縮算法。為了使圖像空間的誤差最小化,為頂點屬性的不同信息(坐標、法向量、紋理坐標)分配不同長度的字段,將頂點數據壓縮為96bit,以壓縮數據的形式送給頂點著色器進行渲染,并在渲染階段實現實時解壓縮操作。為了提高幾何數據的解壓縮速率,德國多個研究機構聯合NVIDIA 等GPU企業(yè)研究面向實時圖形繪制的幾何數據解壓縮算法[20~21]。
綜上,在工業(yè)界和學術界對圖形渲染管線中的數據進行壓縮傳輸一直以來都是一個研究的熱點。
頂點是構成圖元的最基本的要素,它包含了多種屬性如頂點的顏色、頂點坐標、紋理坐標等。在渲染頂點前,需要先指定頂點屬性的基地址,如顏色信息基地址,坐標信息基地址等。在進行頂點處理時,圖形處理器需要從內存中讀出用戶寫入的頂點數據信息來進行處理。對于繪制復雜圖形即含有大量頂點的圖形時,如果采用DrawElements的繪制模式,函數中需要指定大量的頂點索引信息,會占用大量的存儲空間。例如圖1 所示,繪制這樣一個兔子需要35947 個頂點,采用Draw_Elements 時對應的在頂點索引數組中需要35947個索引元素。

圖2 頂點信息
在訪問頂點數據時,會事先指定頂點顏色信息、坐標信息以及其它屬性信息在顯存中的基地址,如上圖2 所示。然后根據要獲取的頂點屬性信息進行頂點抓取。在OpenGL標準中指定了兩種繪制模式:GLDrawArrays和GLDrawElements。當采用DrawArrays 的繪制模式時,該函數需要指定頂點的起始索引,頂點數量以及圖元類型等信息,然后從頂點的起始索引開始,索引值依次加1,一直加到索引值的數量與指定的頂點數量相同為止;當繪制模式為Draw_Elements 時,此函數指定頂點起始索引,頂點的數量,頂點的圖元類型以及一個索引數組等參數,此時的頂點索引為索引數組中指定的值而不是依次加1。在獲取頂點信息時,會根據索引數組中的索引值和頂點數據的類型,加上指定的基地址得到頂點數據在顯存中的地址,并根據此地址在顯存中獲取數據。對于含有重復性頂點的場景時,由于采用DrawArrays 的模式在一次Draw 命令下不會出現相同的頂點索引,當需要重復繪制一個頂點時,相同的頂點信息在顯存中需要重復存儲多次,使得顯存中不同位置會出現相同的頂點數據,浪費了存儲空間也相應地降低了存儲利用率。針對于這種情況,采用DrawElements的繪制模式能很好地降低此浪費情況,頂點信息只需要在顯存中存儲一次,通過索引數組制定的指定的索引去尋址對應的頂點信息即可。對于頂點索引而言,它的數據類型有UNSIGNED_BYTE(無符號8 位整數),UNSIGNED_SHORT(無 符 號16 位 整 數),UNSIGNED_INT(無符號32 位整數)。并且對于復雜的場景,頂點索引的數量大幅度增加,造成了頂點索引對存儲空間的大量占用。由于此種現象的存在,我們可以對頂點索引數據采取一些存儲優(yōu)化方法。
在DrawElements的繪制模式下,由于頂點索引是索引數組指定的,因此需要使用用戶指定的數據格式來存儲每個頂點的索引,占用較大的空間。我們在主機端壓縮頂點索引,存入到顯示緩存中,在GPU端對數據進行解壓,以此減少頂點索引的存儲空間。當GPU 核處理頂點數據時,先對從顯存中取出的頂點索引進行解壓縮,然后根據解壓縮后的數據進行頂點操作。頂點索引數據的處理框架如圖3所示

圖3 整體處理框圖
假設當前采用的頂點索引數據類型的位寬為format_bit 位,顯存中每一行位寬為data_num_bit位。頂點數組的索引壓縮算法如下:
1)求出當前索引數組中的元素相鄰元素之間的索引差值。
2)根據差值對頂點索引號進行分段處理,使得每個片段內的差值范圍盡可能小,并記錄該段內的差值最大的值所對應的位數Max_diff_bit。分段的原 則 為Max_diff_bit*index_num<=data_num_bitformat_bit,分段后每個片段內頂點索引的數量為index_num。
3)保存每個片段內其起始索引號、index_num和相鄰索引間的差值(索引間的差值位寬固定為Max_diff_bit,便于解壓縮處理)。
4)經過上述3 個步驟,對每個片段壓縮后的數據包含起始索引號和索引間的差值。
上述的分段原則可以保證每段的壓縮數據對應著顯存的每一行,以便于解壓縮提取一次數據時數據位寬滿足一次猝發(fā)傳輸。分段處理后的結果如圖4 所示,將若干個頂點索引分為了N-1 個片段,每個片段都對應著顯存中的一行數據(如圖4)。

圖4 分段后結果
經過主機端的壓縮后,在顯存中存儲的為每一段頂點索引的壓縮數據。對頂點索引數據進行解壓縮時,需要先從顯存中讀出壓縮數據,并對每一段的壓縮數據進行解碼,得到每一段的起始索引并且根據當前段的index_num 和Max_diff_bit 按照編號的順序進行相應的解碼處理,通過不斷地迭代處理,用當前的差值加上前一個頂點的索引值,可以得到當前頂點的索引值。依此類推,分別對每一個片段進行解壓縮,解壓縮完成后發(fā)送給計算核心進行著色處理。解壓縮流程與壓縮數據存儲方式如圖6所示。

圖5 解壓縮處理
通過上述步驟可以看出,在采用了此壓縮方法后,頂點索引數組在顯存中的存儲空間明顯地減少了,并且在經過硬件的解壓縮處理后,可以達到無損壓縮的效果,不會對頂點數據的獲取有任何的誤差。
本節(jié)對本文提出的頂點索引壓縮方法進行了驗證和性能分析,在不同的測試場景下,針對于Draw_elements 繪制模式對不同數據類型的頂點索引數組中的元素進行了壓縮,并利用硬件描述語言Verilog實現了硬件解壓縮處理。
利用System Verilog 搭建了解壓縮模塊的驗證平臺,對壓縮數據進行了解壓縮處理,并將壓縮前與解壓縮后頂點索引進行對比驗證,統計其壓縮比。測試結果如表1 所示(da_ty 表示數據類型,number為頂點數量,bit_1 為壓縮前數據位寬,bit_2為壓縮后數據位寬)。

表1 測試結果匯總
測試集如圖6~7所示。

圖6 Triangles

圖7 Rectangles
通過上表可以看出,本文實現的壓縮方法為一種無損壓縮方法,并且可以對頂點索引實現很好的壓縮,減少了存儲資源的占用,達到了預期目標。
頂點索引是GPU 尋址頂點數據的重要部分,尤其是采用繪制模式為Draw_Elements 的情況下,需要用戶自行指定頂點索引號。頂點索引按照順序依次存儲在顯存中,占據了較多的存儲資源。本文通過一種無損壓縮方式,在主機端對頂點索引數組元素進行了一定程度上的壓縮,并在圖形處理器內部通過硬件電路實現了解壓縮過程對于不同場景下,整體的壓縮比率會有差異。最終經過驗證測試后,達到了預期目標。