曰本美女∴一区二区特级A级黄色大片, 国产亚洲精品美女久久久久久2025, 页岩实心砖-高密市宏伟建材有限公司, 午夜小视频在线观看欧美日韩手机在线,国产人妻奶水一区二区,国产玉足,妺妺窝人体色WWW网站孕妇,色综合天天综合网中文伊,成人在线麻豆网观看

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

GPU 性能原理拆解

穎脈Imgtec ? 2025-02-08 14:29 ? 次閱讀

「迷思」是指經(jīng)由人們口口相傳,但又難以證明證偽的現(xiàn)象。由于 GPU 硬件實現(xiàn)、驅(qū)動實現(xiàn)是一個黑盒,我們只能通過廠商提供的 API、經(jīng)過抽象的架構來了解并猜測其原理。因此坊間流傳著各種關于與 GPU 打交道時的性能迷思。比如「移動端的瓶頸是帶寬」、「移動端不需要太在意 Overdraw」、「植被需要做 PrePass」等等。這些優(yōu)化手段,有時候我們對后面的原理一知半解,有時候又會隨著硬件的發(fā)展而逐漸變得不適用,逐漸會變成一種神秘主義。

作者:mobiuschen

我希望可以結合一些現(xiàn)有資料,對這些「迷思」做定性的分析,避免一不小心變成了負優(yōu)化。有條件時,甚至希望可以做一些定量分析的實驗。


移動端架構

fe6e42de-e5e5-11ef-9434-92fbcf53809c.png

fe9b991e-e5e5-11ef-9434-92fbcf53809c.pngfeb422cc-e5e5-11ef-9434-92fbcf53809c.png

我們先簡單過一下幾個廠商的 GPU 架構。蘋果的 GPU 架構查不到任何文檔,只能姑且以多年前 PowerVR 的架構文檔來替代。移動端的 GPU 現(xiàn)在都是 TBDR 架構,分為兩個 Pass:Binning Pass 和 Rendering Pass。Binning Pass 將各個 Primitive 分到各個 Tile,Rendering pass 再在對這些 tile 進行渲染。

講 GPU 結構的資料還是比較多,這里不再贅述。我們只著重講幾點不同架構上有差異、與后面「迷思」相關的功能點。

隱面剔除

「隱面剔除」技術這一術語來自于 PowerVR 的 HSR (Hidden Surface Removal),通常用來指代 GPU 對最終被遮擋的 Primitive/Fragment 做剔除,避免執(zhí)行其 PS,以達到減少 Overdraw 的效果。

Adreno/Mali/PowerVR 三家在處理隱面剔除除的方式是不一樣的。

PowerVR 的 HSR 原理是生成一個 visibility buffer,記錄了每一個 pixel 的深度,用于對 fragment 做像素級的剔除。因為是逐像素級的剔除,因此需要放到 Rasterization 之后,也就是說每個三角形都需要做 Rasterization。根據(jù) visibility buffer 來決定每一個像素執(zhí)行哪個 fragment 的 ps。也因此,PowerVR 將自己 TBR (Tile Based Rendering) 稱為 TBDR (Tile Based Deferred Rendering)。而且特別提到了一點,如果當出現(xiàn)一個 fragment 的深度無法在 vs 階段就確定,那么就會等到 fragment 的 ps 執(zhí)行完,確定了深度,再來填充對應的 visibility buffer。也就是說這個 fragment 會阻塞了 visibility buffer 的生成。這個架構來自于 PowerVR 2015年左右的文檔,后續(xù) Apple 繼承了其架構,但是后面是否有做更進一步的架構優(yōu)化不得而知。

Adreno 實現(xiàn)隱面剔除技術的流程稱為 LRZ (Low Resolution Depth),其剔除的顆粒度是 Primitive 而不是 Fragment。在 Binning pass 階段執(zhí)行 Position-Only VS 時的會生成一張 LRZ buffer (低分辨率的 z buffer),將三角形的最小深度與 z buffer 做對比,以此判斷三角形的可見性。Binning pass 之后,將可見的 triangle list 存入 SYSMEM,在 render pass 中再根據(jù) triangle list 來繪制。相比于 PowerVR 的 HSR,LRZ 由于是 binning pass 做的,可以減少 Rasterization 的開銷。并且在 render pass 中,也會有 early-z stage 來做 fragment 級別的剔除。對于那種需要在 ps 階段才能決定深度的 fragment,就會跳過 LRZ,但是并不會阻塞管線。

Mali 實現(xiàn)隱面剔除的技術稱為 FPK (Forward Pixel Killing)。其原理是所有經(jīng)過 Early-Z 之后的 Quad,都會放入一個 FIFO 隊列中,記錄其位置與深度,等待執(zhí)行。如果在執(zhí)行完之前,隊列中新進來一個 Quad A,位置與現(xiàn)隊列中的某個 Quad B 相同,但是 A 深度更小,那么隊列中的 B 就會被 kill 掉,不再執(zhí)行。Early-Z 只可以根據(jù)歷史數(shù)據(jù),剔除掉當前的 Quad。而 FPK 可以使用當前的 Quad,在一定程度上剔除掉老的 Quad。FPK 與 HSR 類似,但是區(qū)別是 HSR 是阻塞性的,只有只有完全生成 visibility buffer 之后,才會執(zhí)行 PS。但 FPK 不會阻塞,只會kill 掉還沒來得及執(zhí)行或者執(zhí)行到一半的 PS。

fed06d88-e5e5-11ef-9434-92fbcf53809c.png

Vertex Shader 的執(zhí)行

PowerVR 下,VS 是在 Binning Pass 階段執(zhí)行的,只會執(zhí)行一次。

Adreno 和 Mali 都是會執(zhí)行兩次 VS。第一次都是 "PosOnly Vertex Processing",就是只執(zhí)行 VS 中產(chǎn)出 position 相關的指令,只算出 Position 信息給 Binning 階段使用。

第二次 VS 的執(zhí)行,Mali 是在 binning 階段,稱為 "Varying Shading",只執(zhí)行非 Position 的那部分邏輯。而 Adreno 的第二次 VS 的執(zhí)行會放到 rendering 階段,并且是執(zhí)行全量的 VS。

為什么有這個區(qū)別呢?下個點 "VS Output" 會講到。

VS Output

VS 階段產(chǎn)出的數(shù)據(jù)稱為 VS Output,或者稱為 Post-VS Attributes。對這些數(shù)據(jù)的處理,不同架構也不大一樣。

PowerVR,Binning Pass 階段就已經(jīng)執(zhí)行了全量的 VS,然后會將 VS Output 寫到 system memory。在 Rendering Pass 再重新讀回來。

Adreno 架構下,Binning Pass 之后只產(chǎn)出兩種數(shù)據(jù)并會將其寫到 system memory:Primitive List 和 Primitive Visibility。在 Rendering Pass 會重新執(zhí)行一遍 VS,產(chǎn)出 VS Output。這些數(shù)據(jù)不回寫回 system memory,而是存在 On-Chip Memory (LocalBuffer),PS 階段直接可以從 Local Buffer 讀取。

這樣就節(jié)省了很多的帶寬消耗。

Mali 在第五代 GPU 架構 Immortalis 之前,第二遍 VS 會在 Binning Pass 執(zhí)行完,并且把 VS Output 都寫入 system memory,在 rendering pass 重新讀出來。這樣就會有帶寬的消耗。于是第五代架構推出了 Deferred Vertex Shading (DVS),就是將 Varying Shading 延遲到 rendering 階段再執(zhí)行,這樣就直接可以把數(shù)據(jù)存到 On-Chip Memory 給后面的 PS 使用,達到節(jié)省帶寬的目的。

號稱可以節(jié)省 20% -40% 的帶寬。

fee77e06-e5e5-11ef-9434-92fbcf53809c.png

移動端帶寬是瓶頸

帶寬就是單位時間內(nèi)數(shù)據(jù)的傳輸量,其量化標準為「位寬 (bit wide) * 頻率」。在位寬確定的情況下,只能通過增加工作頻率來提高帶寬。更高的頻率意味著需要更高的電壓,進而造成更高的功耗。功率 (P) 與電壓 (V) 的關系 ,也就是說功耗與電壓平方成正比。

「在移動端帶寬是瓶頸」,源自于兩方面:

  1. 帶寬的發(fā)展與算力的發(fā)展不匹配
  2. 帶寬的增加帶來了大功耗

下面這張圖對比了算力、內(nèi)存帶寬、內(nèi)部帶寬的發(fā)展,可以看到 20 年間,硬件算力提升了 60000 倍,內(nèi)存帶寬提升了 100 倍,而內(nèi)部帶寬只提升了 30 倍。公路寬度提升了幾十倍,車流量卻變成了幾萬倍,當然公路的寬度就變成了瓶頸了。

ff06e4f8-e5e5-11ef-9434-92fbcf53809c.png

這個問題在移動端變得更加嚴重。因為在移動端,芯片面積有限,位寬無法做得很大。在手機上,內(nèi)存位寬一般是 64-bit wide 或者 128-bit wide;而桌面端可以是 1024-bit wide,甚至搭配了 HBM (High Bandwidth Memory) 的顯卡可以到 4096-bit wide。更高的位寬意味更高的面積和成本。因此,手機上只能通過提高電壓來增加帶寬。按照前面的公式,功率 (P) 與電壓 (V) 的平方成正比。電壓的增加指數(shù)級地增加了手機的功耗。所以我們經(jīng)常說「手機功耗的大頭就是帶寬」。


不要在 Shader 中使用分支

這是一個經(jīng)典的迷思:「不要在 Shader 中使用分支,使用了之后相當于 Shader 需要在分支兩邊各執(zhí)行一遍」。

這個說法是基于 GPU SP 并行執(zhí)行的原理。SP 在執(zhí)行時,是使用 lockstep 的方式執(zhí)行同一個 wave (或者 warp) 中的所有 fiber (或者 thread)的。也就是說,使用 SIMD 的指令,在一個 cycle 內(nèi)同時執(zhí)行所有的 fiber 相同指令。每一個 fiber 都是同時往前步進的。SP 有個 Mask 的功能,可以在執(zhí)行時屏蔽某些 fiber。這個功能就是用來處理分支的。當遇到分支時,先 mask 掉應該走 false 的 fiber,執(zhí)行 true 的分支;再 mask 掉應該走 true 的 fiber,執(zhí)行 false 的分支。這也就是前面說到的,需要 shader 在分支兩邊各執(zhí)行一遍。

這個功能稱為 "Divergency",不止用在了處理邏輯分支,還用于處理很多其他功能。比如后面會說到的 quad overdraw。

ff2caecc-e5e5-11ef-9434-92fbcf53809c.png

但是,分支條件分為幾種情況:

  1. 常量條件:這種在編譯時就會被優(yōu)化掉,是不會產(chǎn)生分支的。
  2. Uniform 作為條件:如果同個 wave 中的所有 fiber 都是走同一個條件分支,理應也是不會產(chǎn)生分支的。
  3. 運行時的變量決定:這種產(chǎn)生對于性能的影響是最大的

第二點是容易被忽略的

另外,不同的 GPU 架構對于 divergency 的性能敏感程度是不同的。從原理上我們可以猜到,每個 wave 中的 fiber 數(shù)量越多,divergency 的代價就越大。Adreno 中每個 wave 中 fiber 數(shù)量較多,因此收 Divergency 影響會更大。

在 Snapdragon Profiler 中,通過這兩個指標來觀察 Divergency 的情況:% Shader ALU Capacity Utilized 、 % Time ALUs Working。

下面是這倆指標的含義:

% Shader ALU Capacity Utilized:重要指標。當存在 Divergence 時,此 Metrics 會小于 "% Time ALUs Working". 比如 % Time ALUs Working" 為 50%, "% Shader ALU Capacity Utilized" 為 25%,那么意味著一半的 fibers 不工作 (masked due to divergence, or triangle coverage)。

% Time ALUs Working. SP busy 的 Cycles 里,多少比例的 Cycle ALU Engine is Working。一個 Wave 即使只有一個 fiber active,這個 Metrics 也加一。這點與 Fragment ALU Instructions Full/Half 不同。

也就是說,Divergence 的比例 = % Time ALUs Working - % Shader ALU Capacity Utilized


移動端不需要太關注 Overdraw

"Overdraw" 字面意思就是「畫多了」,做多了不必要的工作。通常我們說的 overdraw 是指多個三角形重疊,先畫遠處再畫近處,遠的像素就會被拋棄掉,那么遠的像素這部分的 PS 就被浪費了。

在目前的 TBDR 架構中,在 binning 階段之后,由于通過 vs 有了深度信息,可以利用這個深度信息來剔除遠處的三角形(或像素)的繪制,減少后面 ps 的 overdraw。這個機制,Adreno GPU 稱為 LRZ (Low Resolution Depth),PowerVR GPU 稱為 HSR (Hidden Surface Removal),Mali 稱為 FPK (Forward Pixel Killing)。因此,在這個層面上,這個迷思是正確的。

但是有另外一種 overdraw 原理完全不同,稱為 "Quad Overdraw"。SP 在做 PS 繪制時,并不是以 pixel 為單位,而是以 quad 為單位的,每個 quad 是 4 個像素。如下圖

ff65b988-e5e5-11ef-9434-92fbcf53809c.png

一個 quad 中畫多了的那些 pixel,就是 quad overdraw。一個三角形的面積越大,quad overdraw 的比例就會越小。極端情況下,如果三角形只占據(jù)了 1 pixel,那么就會有 3 pixel 的繪制是浪費的,75% 的 quad overdraw。

Quad overdraw 在 GPU 的實現(xiàn)邏輯,就是 Divergency。因此,在 Adreno 這種對于 divergency 更敏感的架構中,這個問題會變得更嚴重。Adreno 架構一個 wave 最多只能處理 4 個三角形,但卻有 128 個 fiber。極端情況下,每個三角形只占據(jù) 1 個像素,那么 128 fiber 只畫了 4 個有效像素,浪費了 96.9% 的算力。

因此,我們需要盡量減少微小的三角形的出現(xiàn),最直接的辦法就是使用合適的 LOD。這不僅會讓繪制的三角數(shù)量更少,減少帶寬使用,還會讓繪制效率更高。Arm 對此的建議是,建議每個三角形至少覆蓋 10-20 個 fragment。

- Use models that create at least 10-20 fragments per primitive.

驗證 Quad Overdraw,一樣還是用 % Shader ALU Capacity Utilized、% Time ALUs Working 這倆指標。Divergency 比例 = % Time ALUs Working - % Shader ALU Capacity Utilized

為了排除 shader 分支造成的 divergency 的干擾,可以將 shader 都替換為沒有任何分支的簡單 shader。


Shader 復雜度

當我們在說「shader 復雜度」的時候,我們是在說:

  1. Shader 靜態(tài)指令數(shù)
  2. Shader 動態(tài)指令數(shù)
  3. Shader 使用的寄存器數(shù)量

分別討論一下這幾個指標過多過大之后的問題

指令數(shù)量

「指令數(shù)量」分為:靜態(tài)指令數(shù)(static instruction count)和動態(tài)指令數(shù)(dynamic instruction count)。靜態(tài)指令數(shù)是指編譯后的 shader 程序里的指令數(shù)量;動態(tài)指令數(shù)則是被執(zhí)行的指令數(shù)量。比如,使用 [unroll] 展開 for 循環(huán),那么編譯出來的程序的靜態(tài)指令數(shù)就會比沒有展開的多。但無論是否展開,運行兩個程序的動態(tài)指令數(shù)應該是一樣的。

Offline compiler 統(tǒng)計出來的都是靜態(tài)指令數(shù),但是可能會也會統(tǒng)計出的最短執(zhí)行路徑的動態(tài)指令數(shù)。

當靜態(tài)指令數(shù)量過多時,cache 就會裝不下。Snapdragon Profiler 中有對應的指標:

% Instruction Cache Miss: 不要讓 Shader (編譯后機器)指令超過 2000 條(VS+PS),用 SDP 的 Offline Compiler 可以看到指令數(shù)

寄存器數(shù)量

Shader Processor (SP) 中使用寄存器來保存 shader 的上下文。如果 shader 的寄存器使用過多,當需要通過切換執(zhí)行的 shader 來 hide latency 時,寄存器數(shù)量不足而無法切換,進而導致執(zhí)行效率下降。

什么是 "Hide Latency" 呢?就是當 SP 當前執(zhí)行的 shader 發(fā)生 long latency 時(比如貼圖采樣),為了提高利用率,SP 會切換到另一個 shader 來執(zhí)行而不是干等。這就稱為 "Hide Latency"。是否可以切換成功的條件是,寄存器在保留原 shader 上下文的基礎上,是否足以可以容納新 shader 的上下文。如果某個 shader 需要多寄存器較多,當前的寄存器已經(jīng)放不下了,就會導致切換失敗。

貼圖采樣、Storage Buffer 訪問都會造成 latency,寄存器使用的數(shù)量會影響 hide latency 的效率。因此,我們要避免同時貼圖采樣數(shù)量多而又計算過程復雜(寄存器使用數(shù)量多)的 shader。

當占用寄存器數(shù)量繼續(xù)增大,大于 on-chip memory 的尺寸時,會出現(xiàn) "Register Spilling"。也就是寄存器存不下來,只能放到 system memory 里了,那么性能就會出現(xiàn)斷崖式下降。

寄存器數(shù)量是移動端 GPU 和桌面端一個大的差異點。驍龍888 是 64KB 每 64 ALU,而 nVidia/AMD 是 256KB 每 64 ALU。這直接決定了兩端 shader 的復雜程度。桌面端的 shader 拿到移動端來跑,性能的下降并不是和指令數(shù)量不是成線性關系,而會因為寄存器容量不足,導致 shader 無法充分地切換、甚至出現(xiàn) spilling 而執(zhí)行效率非常低下。

使用 Offline Compiler 中的: register footprint per shader instance 來看 shader 寄存器的使用數(shù)量。

在 Snapdragon Profiler 中可以通過 % Shader Stalled 來判斷 shader 的執(zhí)行效率。當 SP 無法切換到其他 shader 去執(zhí)行時,就會出現(xiàn) stall。

% Shader Stalled: 指沒有任何 execution units (主要是指 alu, texture & load/store) 在工作的 cycles 占總 Cycle 數(shù)的比例。Memory fetch stalled 不一定意味著 Shader Stalled,因為如果 shader 還能找個某個 wave 執(zhí)行 ALU,那么不算 stall。% Shader Stalled 意味著 IPC (instruction per cycle) 下降。


移動端 Vertex Shader 是性能敏感的

移動端,vertex shader 性能敏感有幾層原因:

首先,在 TBR 架構中,跨 tile 的三角形在每個 tile 中都會被執(zhí)行。如果開啟了 MSAA,那么 tile size 就會變小,那么跨 tile 的三角形數(shù)量就會變多,vs 壓力會變得更大。

其次,就是前面架構部分說到的,在 Adreno/Mali 架構中,VS 都會被執(zhí)行 2 次。在 iOS 中只在 binning pass 階段執(zhí)行一次 VS,render pass 只執(zhí)行 PS。

Adreno/Mali 在 binning pass 中,并不是執(zhí)行全量的 VS,而是只執(zhí)行與 position 相關的指令。一般里說,position 的計算只需要做座標系轉(zhuǎn)換。但如果涉及復雜計算或者貼圖采樣,那么這部分開銷就被放大。比如,在地形繪制時通過采樣高度圖來計算頂點位置。

第三,Vertex Output 也會影響管線執(zhí)行效率。這是跟硬件實現(xiàn)相關的。

在 Adreno 架構中,vertex output 是不需要 resolve 到 SYSMEM 的。每個 SP 中的 Local Buffer 里有一小塊區(qū)域是用來存 vs output 的,可以在 ps 階段使用。但是這部分的區(qū)域是有限的,在 8Gen2 中只有 8KB。如果 SP 中這塊區(qū)域滿了,就會出現(xiàn) vs stall。如果一個 vs output 是 12 個 float4 attribute,那么 8KB 可以裝 64 個 fragment。

在 Mali 的第五代 GPU 架構 Immortalis 之前,在 render pass 中執(zhí)行的 vs 產(chǎn)生的 vs output 是會 resolve 到 SYSMEM,在 ps 中再 load 回來。這樣就產(chǎn)生了帶寬開銷。第五代 GPU 架構引入了 Deferred vertex shading (DVS) pipeline,可以省去 vs output resolve/unresolve 的過程,對帶寬有較大的改善。官方的說法是 20% - 40% 的帶寬。但可以想象,這部分肯定也是有存儲上限的。

總結來說,就是

  1. 啟用 MSAA 會加重 VS 的壓力
  2. VS 中 position 計算部分不要用過重的邏輯,尤其不要使用 data fetch、貼圖采樣。
  3. 要控制 VS Output 的數(shù)據(jù)量,數(shù)據(jù)量過大,可能會造成 vs stall;對于 mali 舊機型、iOS,會增加帶寬使用。


是否要做 PrePass

這個問題會比較復雜。

我們重新看看前面 Adreno 的架構圖:在 Binning pass 階段會做 LRZ (Low Resolution Z,也就是低分辨率的深度圖) 剔除。接著在 Rendering pass 階段會做 early-z 和 late-z。LRZ Test 是做低分辨率、primitive 顆粒度的深度剔除;Early-Z、Late-Z 是做全分辨率、quad 顆粒度的深度剔除。

對于 Opaque 物體,在 LRZ/Early-Z 階段,會去做不同顆粒度的 Test & Write;在 Late-Z 就無需再做測試了。

對于 Translucent (Alpha Blend) 物體,不可以 Write。但是因為有可能會被更近的深度剔除掉,所以可以 Test。

對于 Mask (Alpha Test) 物體,深度其實在 VS 階段就可以確定了,但是因為可能在 ps 階段被 discard 掉,所以在 LRZ、Early-Z 階段都只能 Test 不能 Write,需要到 Late-Z 才能 Write。

對于 Custom Depth (oDepth) 的物體,只會在 Late-Z 寫深度,且不會被深度剔除。oDepth 是 pixel shader output depth register,專門指 ps 階段寫深度的寄存器。

LRZEarly-ZLate-Z
OpaqueTest & WriteTest & WriteOff
Translucent (Alpha Blend)TestTestOff
Masked (Alpha Test)TestTestWrite
Custom Depth (oDepth)OffOffWrite

有了上面的梳理,我們再來看看這個迷思。

PrePass,在桌面端的傳統(tǒng)做法,是針對 Opaque 先跑一遍 PositionOnly 的較為簡單的 Shader,生成深度圖給后面的 BasePass 使用。以達到減少 overdraw 的目的。但是對于移動端來說,由于 binning pass 的 LRZ 已經(jīng)做了類似的事情,因此移動端的 Opaque 物體是沒必要做這個事情的。

對于「移動端是否要做 PrePass」的討論,一般主要集中在 Mask 物體。Mask 物體無法在 LRZ/Early-Z 階段寫深度,那么對于大面積的 Mask 物體就會造成 overdraw。如果大量的 mask 物體穿插在一起(比如植被),開銷就跟畫一堆透明物體一樣。

并且對于不同的架構,Mask 的沖擊是不一樣的。

對于 PowerVR 的架構下,"Overdraw Reducing" 是使用了 HSR (Hidden Surface Removal)。這是一個 Fragment 顆粒度的可見性剔除,在 binning pass 階段會輸出一張全分辨率的 visibility map,在 render pass 中只需要執(zhí)行 ps 而無需再執(zhí)行 vs。因此可以無視 drawcall 提交順序。

With PowerVR TBDR, Hidden Surface Removal (HSR) will completely remove overdraw regardless of draw call submission order.

但如果遇到 alpha test,那就很難受了。需要等到 ps 執(zhí)行完得到真實深度了,再 feedback 到 HSR。這個 feedback 是否會 stall 后面的 drawcall 呢?資料中沒有明確地提及。由于需要根據(jù) HSR 產(chǎn)生的 visibility map 去做 render pass,所以可以猜測就算不會 stall 后面的 drawcall,也會 stall 整個 HSR。

對于 Adreno/Mali 架構,雖然 Mask 不會造成管線 stall,但是混雜了 Opaque 和 Mask 的渲染 pass,對管線的執(zhí)行效率也是有影響。因此也是建議將 Opaque/Mask 作為兩個 pass 來渲染。

默認的處理方案,是將 Opaque 和 Mask 分成兩個 pass 來渲染,避免 Mask 對渲染管線的阻塞。

在默認方案之上,可以考慮針使用專門的簡化的 vs/ps 對 Mask 物體先做一遍 PrePass,然后在 BasePass 階段 Mask 物體就無需標記為 Alpha Test 了,只需要將 Depth Test 設成 Equal。因為 Mask 物體需要執(zhí)行 ps 才能得到深度,因此需要一個簡化到只做采樣 alpha 的專門 ps。

總結來說,Mask 的 PrePass 的意義在于用一批簡單的 drawcall 來換取 BasePass 的管線執(zhí)行效率、減少 overdraw。

PowerVR 架構下,不會讓 alpha test 的 late-z 成為 HSR 的瓶頸;Adreno/Mali 架構下,不存在 stall pass 的問題,PrePass 更大的意義在于可以參與去剔除 BasePass 中的物體,無論是 Opaque/Translucent/Masked。

但這批「簡單的 drawcall」當然也有開銷,PrePass 是否一個正優(yōu)化,需要根據(jù)場景類型、機型來做 perf tuning。


運行 CS 可以更高效地利用 GPU

現(xiàn)在都 Shader Processor (SP) 都是 unified design,一個 SP 可以執(zhí)行 VS/PS/CS,不會有專門用于跑 CS 的 SP。因此單獨地跑 raster pipeline 并不會造成硬件利用率不高。并且在 SP 工作在 VS/PS 下,和工作在 CS 下是兩種不同「工作模式」。切換成本根據(jù)硬件而有所不同。

如果在 VS/PS 和 CS 可以「同時」跑在同一個 SP 上,這個功能稱為 Async Compute。這個「同時」是打引號的,是指 SP 上可以有 graphics wave 和 compute wave 互相切換,用來 hide latency。在這個層面上講,確實是可以更高效地利用 GPU。

但是對于結對同時運行的 graphics 和 compute 最好在資源使用上最好是匹配互補的。比如,好的匹配:

  • Graphics: Shadow Rendering (Geometry limited)
  • Compute: Light Culling (ALU Heavy)

壞的匹配:

  • Graphics: G-Buffer (Bandwidth limited)
  • Compute: SSAO (Bandwidth limited)

目前 iOS 是移動端支持 Async Compute 支持最好的。Mali 也是支持的,但更多的細節(jié)需要測試。但 Adreno 到目前為止還是不支持的。


GPU Driven 在移動端的技術限制

GPU Driven 是在桌面端一種非常細顆粒度的三角面剔除 + 合批方案,但是在移動端鮮有應用。雖然其目的是「GPU 性能換取 CPU 性能」,但在移動端對于 GPU 的性能沖擊跟 CPU 的性能優(yōu)化是不匹配的。

究其原因,主要有兩個:

  • 低效的 Storage Buffer 隨機訪問
  • 大量的 small drawcall,以及 instanceCount=0 的 invalid drawcall

GPU Driven 中,"PerInstance" 的 vertex stream 里存放的是指向各個 storage buffer 的 index。這些 storage buffer 存的是 Instance Transform、Material Data、Primitive Data 等信息。在 VS 中通過 index 索引這些 storage buffer 獲取有效數(shù)據(jù)。原先這些數(shù)據(jù)都是通過 instance buffer (vertx stream) 或者 uniform buffer 來獲取的,在 on-chip memory 上就可以很快的獲取到。改為 storage buffer 之后,這些 buffer 一般都比較大,on-chip memory 和 L1/L2 都是存不住的,大概率都要到 SYSMEM 去拿數(shù)據(jù),因此效率很低。

尤其是 instance transform,是會參與 vs 的 position 計算的。在移動端就會導致這部分計算要跑兩遍。

地道的 GPU Driven 會做 cluster 級別的剔除,一個 cluster 可能是 64/128 個三角形。每個 cluster 作為一個 indirect drawcall 的 sub-drawcall 來繪制。如果這個 cluster 被剔除,那么這個 sub-drawcall 的 instance count 就會被寫為 0。這種處理方式,一方面產(chǎn)生非常多的 small drawcall,另一方面產(chǎn)生了很多的 instanceCount=0 的 invalid drawcall

GPU 有專門的用來生成 wave 的組件,Adreno 的叫 HLSQ (High Level Sequencer),Mali 的叫 Warp Manager。這些組件會預讀取若干個 drawcall 來生成 wave,以便可以互相切換。但移動端這塊能預讀取的數(shù)量是比較有限的,比如 Adreno 8Gen1 的 HLSQ 就只能預讀取 4 個 drawcall。如果這些是 small drawcall 或者 invalid drawcall,那就導致喂不飽后端的管線。


最后

破除迷思的辦法,就是摒棄神秘主義,知其然知其所以然。希望這些可以為我們后面的優(yōu)化帶來更清晰的思路和方法,而不是盲人摸象。

貫徹費曼學習法,這也算是我自己個人在這方面所了解的東西的一個總結。

但作為應用層,終究只能在廠商構筑的黑盒之外摸索和猜測。所以難免會有很多不正確、不詳盡、過時的東西。望見諒。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • gpu
    gpu
    +關注

    關注

    28

    文章

    4889

    瀏覽量

    130473
  • 蘋果
    +關注

    關注

    61

    文章

    24521

    瀏覽量

    202641
  • 硬件
    +關注

    關注

    11

    文章

    3448

    瀏覽量

    67066
收藏 人收藏

    評論

    相關推薦
    熱點推薦

    手機散熱器拆解

    隨著智能手機性能的不斷提升,其運行過程中產(chǎn)生的熱量也日益增加,如何有效散熱成為用戶關注的焦點。為此,市場上涌現(xiàn)出各種手機散熱器,旨在幫助手機在高性能運行時保持適宜的工作溫度。在散熱器使用一段時間后
    發(fā)表于 09-25 15:46

    【電子拆解無極限】華為超薄旗艦Ascend P1真機拆解

    沒見過電子實物拆解的不是電子工程師,沒親手拆解過電子產(chǎn)品的不是好工程師。某牛工程師拆解的華為手機,發(fā)給大家看看。拆解有風險,模仿需謹慎。華為超薄旗艦Ascend P1真機
    發(fā)表于 04-24 15:54

    GPU

    的核心處理器。GPU是顯卡的“心臟”,也就相當于CPU在電腦中的作用,它決定了該顯卡的檔次和大部分性能,同時也是2D顯示卡和3D顯示卡的區(qū)別依據(jù)。圖形處理芯片。GPU能夠從硬件上支持T&L
    發(fā)表于 01-16 08:59

    NVIDIA火熱招聘GPU性能計算架構師

    這邊是NVIDIA HR Allen, 我們目前在上海招聘GPU性能計算架構師(功能驗證)的崗位,有意向的朋友歡迎發(fā)送簡歷到 allelin@nvidia.comWechat
    發(fā)表于 09-01 17:22

    GPU加速XenApp/Windows 2016/Office/IE性能會提高嗎

    配置文件來了解3D / GPU / HDX性能。 XenApp服務器運行的是帶有4個vCPU和48GB RAM的Windows Server 2016映像。在性能測試期間,我一直在使用GPU
    發(fā)表于 09-12 16:24

    如何在vGPU環(huán)境中優(yōu)化GPU性能

    大家好,我收到了關于如何在vGPU環(huán)境中優(yōu)化GPU性能的兩個請求,并認為這將是我們的GRID論壇上的一個很好的線程,每個人都可以在他們?nèi)绾挝⒄{(diào)vGPU環(huán)境方面添加他們的經(jīng)驗。讓我從一些公共資源開始
    發(fā)表于 09-29 14:18

    big.LITTLE和GPU相結合可以實現(xiàn)性能和功耗的最佳匹配

    big.LITTLE和GPU相結合實現(xiàn)性能和功耗的最佳匹配
    發(fā)表于 02-02 07:00

    GPU爆炸式發(fā)展背后的深層原因?

    Bifrost架構如何提高效率和性能?Mali-G71如何通過創(chuàng)新技術來提升GPU性能?GPU爆炸式發(fā)展背后的深層原因?
    發(fā)表于 03-11 06:48

    分享一下RK3399處理器的GPU和CPU性能方法

    分享一下RK3399處理器的GPU和CPU性能方法
    發(fā)表于 03-07 06:36

    如何使用iMX8mmini提高GPU性能

    我正在使用 iMX8mmini 并嘗試提高 GPU 性能。使用下面的命令我發(fā)現(xiàn)當前 GPU 以 500 MHz 的頻率運行。根據(jù)數(shù)據(jù)表或設備樹節(jié)點,GPU 以 800 MHz 的標稱頻
    發(fā)表于 04-18 07:17

    Mali GPU性能分析工具

    本文檔描述了馬里GPU性能分析工具2.2版中的已知勘誤表。 這是一個貫穿整個產(chǎn)品生命周期的工作文檔,因此,隨著新信息的發(fā)現(xiàn),其內(nèi)容可能會被修改。 本文中包含的信息是ARM有限公司的財產(chǎn),對錯誤或遺漏
    發(fā)表于 09-05 07:08

    選擇GPU服務器需要考慮哪些情況如何才能提升GPU存儲性能

    GPU是我們常用器件,采用GPU,才使得圖形顯示成為可能。在上期文章中,小編對GPU的加速原理等知識有所闡述。為增進大家對GPU的認識,本文將基于兩點介紹
    的頭像 發(fā)表于 02-08 17:37 ?3614次閱讀

    GPU性能服務器配置

    GPU性能服務器作為提升計算速度和效率的關鍵設備,在各大應用場景中發(fā)揮著越來越重要的作用。在此,petacloud.ai小編為你介紹GPU性能服務器的配置要點。
    的頭像 發(fā)表于 10-21 10:42 ?668次閱讀

    如何提高GPU性能

    在當今這個視覺至上的時代,GPU(圖形處理單元)的性能對于游戲玩家、圖形設計師、視頻編輯者以及任何需要進行高強度圖形處理的用戶來說至關重要。GPU不僅是游戲和多媒體應用的心臟,它還在科學計算、深度
    的頭像 發(fā)表于 10-27 11:21 ?1982次閱讀

    ?為什么GPU性能效率比峰值性能更關鍵

    在評估GPU性能時,通常首先考察三個指標:圖形工作負載的紋理率(GPixel/s)、浮點運算次數(shù)(FLOPS)以及它們能處理計算和AI工作負載的每秒8-bittera運算次數(shù)(TOPS)。這些關鍵
    的頭像 發(fā)表于 03-13 08:34 ?243次閱讀
    ?為什么<b class='flag-5'>GPU</b><b class='flag-5'>性能</b>效率比峰值<b class='flag-5'>性能</b>更關鍵