本文介紹在 NVIDIA GPU 上使用著色器時的最佳實踐。要在應用程序中獲得高且一致的幀速率,請參閱高級 API 性能小貼士。
著色器通過使您能夠控制渲染過程的各個方面,在圖形編程中發揮著關鍵作用。它們在 GPU 上運行,負責操作頂點、像素和其他數據。
- 常規著色器
- 計算著色器
- 像素渲染
- 頂點著色器
- 幾何體、域和外殼著色器
常規著色器
這些提示適用于所有類型的著色器。
推薦
- 避免扭曲發散常量緩沖區視圖(CBV)和即時常量緩沖區(ICB)讀取。
- 當扭曲中的線程統一訪問數據時,恒定緩沖區讀取最有效。如果需要發散讀取,請使用著色器資源視圖(SRV)。
- SRV 應優先于 CBV 的典型情況包括:
- 骨骼或蒙皮數據
- 查找表,如預先計算的隨機數
- 要優化緩沖區和組共享內存,請使用手動位打包。在創建用于打包數據的結構時,請考慮字段可以容納的值的范圍,并選擇可以包含該范圍的最小數據類型。
- 通過提供預期運行時行為的提示來優化控制流。
- 確保啟用編譯標志-為 DXC 綁定的所有資源(或 D3DCOMPILE_all_resources_bound 在 FXC)如果可能的話。這樣可以實現一組更大的驅動程序端優化。
- 考慮在適當的情況下使用 FLATEN 和 BRANCH 關鍵字。
- 條件分支可能會阻止編譯器提升長延遲指令,例如紋理獲取。
- FLATTEN 關鍵字提示編譯器可以在對語句求值之前自由地提升和啟動加載操作。
- 使用根簽名 1.1 指定靜態數據和描述符,使驅動程序能夠進行最佳著色器優化。
- 盡量減少寄存器的使用。寄存器分配可能會限制占用率,并可能迫使驅動程序將寄存器溢出到內存中。
- 加載單通道紋理四邊形時,首選使用聚集指令。
- 與由連續樣本指令構建的等效操作相比,這將使預期延遲減少近 4 倍。
- 比起原始緩沖區,更喜歡結構化緩沖區。
- 結構化緩沖區具有更嚴格的對齊要求,這使驅動器能夠調度更高效的加載指令。
- 考慮在數學密集型著色器(例如,物理模擬和去噪器)中使用超越函數(exp、log、sin、cos、sqrt)的數值近似或預計算查找表。
- 為了在 TEX 單元中促進快速路徑,最高可加速 2 倍,在某些情況下使用點過濾:
- 點過濾已經是精確表示的低分辨率紋理。
- 正在以其本機分辨率訪問的紋理。
不推薦
- 不要認為半精度浮點運算總是比全精度浮點運算快,反之亦然。
- 在 NVIDIA Ampere GPU 上,執行 FP32 和執行 FP16 指令一樣高效。在精確格式之間轉換的開銷可能會以凈損失告終。
- NVIDIA Turing GPU 可能受益于使用 FP16 數學,因為 FP16 的發布速率是 FP32 的兩倍。
計算著色器
計算著色器用于從數據處理和模擬到機器學習的通用計算。
推薦
- 如果可能進行跨線程通信,請考慮在組共享內存上使用 wave 內部函數。
- Wave 內部函數不需要顯式的線程同步。
- 從 SM 6.0 開始,HLSL 本機支持 warp wide wave intrinsic,而無需使用特定于供應商的 HLSL 擴展。只有在缺少預期功能時,才考慮使用特定于供應商的 API。有關詳細信息,請參閱 在 HLSL 中解鎖 GPU Intrinsics。
- 要增加原子吞吐量,請使用 wave 指令跨扭曲合并原子操作。
- 為了最大化緩存位置并提高 L1 和 L2 命中率,請嘗試對全屏計算過程進行線程組 ID 刷新。
- 一個好的起點是以對應于兩到八次翹曲的線組大小為目標。例如,全屏通道的線程組大小為 8x8x1 或 16x16x1。確保對著色器進行評測,并根據評測結果調整尺寸。
不推薦
- 不要使線程組的大小難以按平臺和 GPU 架構進行縮放。
- 專業化常數可以在 Vulkan 中用于在管道創建時設置維度,而 HLSL 要求在著色器編譯時知道線程組大小。
- 注意線程組啟動延遲。
- 如果您的 CS 具有在大多數情況下預計會提前退出的提前退出條件,則最好選擇更大的線程組維度,并減少啟動的線程組總數。
像素渲染
像素著色器,也稱為片段著色器,用于按像素計算效果。
推薦
- 與像素著色器中的手動深度測試相比,更喜歡使用深度邊界測試或模具和深度測試。
- 深度和模板測試可能會丟棄整個 16×16 光柵瓦片,直至單個像素。確保 Early-Z 已啟用。
- 注意可能迫使駕駛員禁用 Early-Z 測試的使用模式:
- 有條件的 z 寫入,如剪輯和丟棄
- 另一種選擇是考慮使用 null 混合操作
- 像素著色器深度寫入
- 寫入無人機資源
- 有條件的 z 寫入,如剪輯和丟棄
- 如果扭曲之間的延遲差異很大,請考慮將全屏過程轉換為計算著色器。
不推薦
- 不要廣泛使用光柵順序視圖(ROV)技術。
- 保證訂單不是免費的。
- 始終與高級混合操作和原子學等替代方法進行比較。
頂點著色器
頂點著色器用于在逐頂點的基礎上計算效果。
推薦
- 更喜歡使用壓縮頂點格式。
- 與 CBV 相比,更傾向于使用 SRV 對數據進行蒙皮。這是 CBV 讀數不同的典型情況。
幾何體、域和外殼著色器
幾何體、域和外殼著色器用于控制、評估和生成幾何體,從而使鑲嵌能夠創建曲面和對象的動態生成。
推薦
- 使用 NVIDIA Turing 中引入的網格著色功能替換幾何體、域和外殼著色器。
- 使用以下配置啟用快速幾何體路徑:
- 固定拓撲:擴展或減少頂點數量。
- 固定基元類型:輸入基元類型等于輸出基元類型。
- 不可變的逐頂點屬性:應用程序無法更改頂點屬性,只能將它們從輸入復制到輸出。
- 每基元屬性可變:應用程序可以為整個基元計算一個值,然后將其傳遞到片段著色器階段。例如,它可以計算三角形的面積。
鳴謝
感謝 Ryan Prescott、Ana Mihut、Katherine Sun 和 Ivan Fedorov。
?