GPU架构杂乱备忘——IMR、TBR、TBDR
原文:https://juejin.cn/post/6844904132864655367
GPU架構雜亂備忘——IMR、TBR、TBDR
之前覺得涉及到gpu架構相關的問題只需要知道個大概就好,畢竟在圖形api的層面上應該把硬件的細節給隱蔽掉,gpu的架構千千萬萬,每家廠商每個型號都不一樣,開發者沒必要掉進這個細節里面。但是最近重看Metal,特別是2.0之后新增的功能,逐漸深刻意識到一個事實——圖形api已經迎來了真正的第三代。當然DX12、Vulkan和Metal在誕生時就打出了“現代圖形api”的旗號,與傳統api劃出界限,我也只算是后知后覺。這些現代圖形api的一個特點就是開放更多操縱硬件的細節,全權交給開發者來定奪。不過真正讓我覺得有必要深入了解一下gpu架構的原因卻是Metal在面對桌面級gpu和移動級gpu給出了差異相當大的兩套api,這也讓桌面端和移動端的圖形編程變得截然不同。
桌面級gpu架構——IMR(Immediate Mode Rendering)
IMR就是我們普遍熟悉和使用的gpu架構,以n卡為例從Tesla發展到Turing依舊還是IMR架構。這種架構也和之前的圖形api與渲染管線天然契合。每一個繪圖的指令來到顯卡,顯卡便立即執行,從頭到尾跑完整個管線,最終將結果輸入到Frame Buffer中。但是這種架構有一個問題,在開啟深度測試后,每個fragment的輸出都要和Depth Buffer中的深度值進行深度測試,如果通過測試則需要更新Depth Buffer和Frame Buffer。這個過程包括了對System Memory的一次讀取和兩次寫入,而fragment的數量巨大,這樣就帶來了很大的訪問System Memory的壓力。而IMR的解決辦法則是給gpu配備足夠大緩存和足夠大的帶寬。不過代價卻是顯卡為了容納下更多緩存使得主板越來越大,并且頻繁大量的帶寬訪問造成巨大的耗電與發熱而不得不增加單獨的風扇。這些代價在桌面電腦上尚能接受,可到了移動端就變成了洪水猛獸。無論是物理空間還是耗電對于移動設備來說都彌足珍貴,也因此不得不推出一種全新的gpu架構
移動級gpu架構——TBR(Tile Based Rendering)
TBR架構在gpu很近的位置增加了一片高速緩存,通常被稱為Tile Memory(圖中也叫On-Chip Buffer)。受限于成本、耗電等原因這塊緩存不會很大,大概幾十k這個量級。首先整個屏幕的畫面會被分割成無數個小塊,被稱為tile,通常32*32大小,這樣Tile Memory中足夠容納得下這個tile的相關數據。當一個繪圖指令抵達顯卡時,不在像IMR一樣立即完成渲染,而是將通過vertex shader和裁剪后的頂點數據,根據所在tile進行分組,并將分組后數據存儲到System Memory中,這塊緩存也被稱為Parameter Buffer (PB, 圖中Primitive List和Vertex Data),然后處理下一個繪制指令。當所有繪制指令的頂點數據都做好處理存進PB或是PB達到一定容量之后才開始進行管線的下一步,即顯卡會以tile為單位從PB中取回相應的頂點數據,進行光柵化、fragment shader以及逐片元處理。原本在逐片元處理中需要頻繁的訪問System Memory變為代價極低的對Tile Memory的訪問。直到這個tile的frament將數據全部更新到Tile Memory上之后,再將該Tile Memory中的數據寫回System Memory,然后執行下一個tile的處理。相比于imr零碎的大量的不可估計的對于System Memory的讀寫操作,TBR中變為了有限的(和tile數量一致)整塊的寫操作。雖然PB也在System Memory上,但是對于PB的訪問是頂點數量級的(顯然vertex要遠小于fragment)且數據會經過特殊的壓縮處理,所以這個置換依舊值當。
不過這種架構也帶來了一些問題,因為渲染管線會在中途中斷,這就導致在這時切換Frame Buffer變得異常麻煩。TBR的做法是會將緩存的渲染數據全部強制繪制,繪制完畢后再些換到新的Frame Buffer,這無形中就增加Tile Memory和System Memory之間數據的拷貝。也因此在移動設備上切換Frame Buffer的使用要十分慎重。但從另一方面來看那些渲染數據并沒有立刻渲染,而是緩存了起來,這也帶來了很大的優化空間。
更強的移動級gpu架構——TBDR(Tile Based Deferred Rendering)
將TBDR放在這里可能會造成一種誤解,認為TBDR是TBR的升級版。事實上,TBDR的是Imagination公司所獨有的一種移動級gpu架構,被廣泛應用于旗下PowerVR等產品中。由于其相比同時期其他TBR架構的顯著優勢受到蘋果公司的青睞,而被搭載到iphone上。近幾年iphone已經開始使用完全自研的A系列處理器也依舊是延續著TBDR架構。TBDR的優勢在于利用PB中緩存的頂點數據,提前對流入到管線剩余部分的片段進行了篩選,來解決傳統渲染管線的一個老大難問題——過度繪制(over draw),而實現這一步的關鍵就在于HSR(Hidden Surface Removal)技術。
如上圖所示Image Synthesis Processor (ISP)從PB中逐圖元的取回當前tile的頂點數據(只有頂點數據),ISP會對數據進行差值并對差值得到的片元數據計算深度,并進行深度和模板測試。如果通過測試,則更新片上的深度和模板緩存,同時在tag buffer中記錄該片元的圖元id。當一個tile的所有圖元都經過ISP的處理后,tag buffer中便會得到每個像素所對應的唯一可見的圖元id。然后對這些可見的圖元,以圖元為單位從PB中取回頂點之外的其他varying數據(比如uv之類)通過TSPF進行差值,然后傳給fragment shader。這也解釋了TBDR總流程圖中vertex data的兩條分支,*1代表流入ISP的頂點數據,*2代表流出TSPF的其他數據。
TBDR也有一些弊端,比如那些在fragment shader中會丟棄的片元(alpha 測試)無法再fragment shader之前直到其是否需要繪制,因此對于這些片元需要通過上圖中的GCS提前提交給fragment shader并計算出確切深度后返回給ISP,這個過程阻塞掉其他片元的計算,因此是一種比較昂貴的代價。另外對于半透明物體(alpha混合)由于一個片元的顏色不僅由最近片元決定,所以此時會強制繪制緩存的片元,這樣便也增加了Tile Memory和System Memory之間的拷貝。因此應該將物體分組,先開啟深度測試繪制非透明物體,再關閉深度測試繪制透明物體。
雖說HSR這種技術被Imagination申請了專利,并且在狹義上只有應用了HSR技術的顯卡在能叫TBDR。但其他廠商也有自己針對TBR架構的優化,比如Arm的Forward Pixel Kill和驍龍的Flex Render都在力圖減少過度繪制。同時在軟件層面也有被稱為TBD(Tile Based Deferred Shading)的著色管線,不過這和TBDR完全是兩個層級的概念。
再看IMR、TBR和TBDR
IMR和TBR因為這塊Tile Memory帶來了完全不同的渲染流程,有些原本適用的法則,在移動端上則完全不一樣。除了上面提到過的切換FBO,alpha測試以及alpha混合等問題。比如在IMR上,每一幀clear是完全不必要的,因為整個屏幕都會被重新繪制而覆蓋掉上一幀的內容。但對TBR來說每一幀不clear則以為著需要在每一個tile開始的時候將上一幀的數據拷貝到Tile Memory中,為防止這種完全沒必要的拷貝所以在TBR上需要每幀clear。如果考慮到TBR中Tile Memory的寶貴以及訪問System Memory的難度,紋理采樣也變成了一種昂貴的操作。紋理數據是存儲在System Memory上,少量近期訪問過的紋理會緩存在Tile Memory中,因此使用壓縮紋理可以讓有限的Tile Memory緩存更多的紋理數據,同時LUT(Look-Up Table)這種不符合空間局部性的紋理數據會大幅降低緩存命中應該少用。
TBR這樣一種為了適合移動端種種限制而不得不誕生一種“妥協”的架構,雖有上述的種種限制,但卻也帶了意想不到威力。這塊神奇的Tile Memory不僅帶來了可以忽略的讀寫成本,也為渲染管線提供了一塊臨時的緩存。這塊緩存的意義就在于,原本多個pass才能完成的渲染流程變成一個pass就可以。為了實現這種優化,在Metal 2.0中提供ImageBlock和Tile Shader等技術,允許開發者對Tile Memory上的數據進行編程,這也讓移動端和桌面端渲染管線的實現有了極大的不同
總結
以上是生活随笔為你收集整理的GPU架构杂乱备忘——IMR、TBR、TBDR的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 通俗来理解 ARM芯片内核,架构,指令集
- 下一篇: FT232RL USB串口与GP232R