圖形開發者和發燒友的一大消遣方式是比較 GPU 的規格,并驚嘆于每一代新一代產品中著色器核心、RT 核心、萬億次浮點運算能力和整體計算能力的不斷增加。實現這些數字所代表的最大理論性能是圖形編程領域的一大關注點。大量渲染數據(例如三角形、像素和光線)流經高度并行的 GPU 計算管線,就像在制造工廠的一組裝配線上一樣。最大吞吐量要求工廠持續運行,不會中斷工作或設備閑置。
本文介紹了 Nsight Graphics 2024.3 中的幾個新功能,幫助您了解和管理這些虛擬裝配線,并為游戲和圖形應用程序創建優化的并行工作負載。
每個線程束的活動線程直方圖?
線程束 是一組 32 個線程,構成可編程著色器的基本執行單元。使用 HLSL 或 GLSL 編寫的光線追蹤、計算、頂點、像素和其他類型的著色器可編譯為機器指令,并最終在線程束大小的硬件組上運行。線程束中的線程并行運行,數百個線程束本身并行運行。當可編程著色成為工作負載的限制因素時,高效運行線程束對于達到峰值性能至關重要。
線程束在名為 Streaming Multiprocessor (SM) 的硬件單元上運行,并使用名為 Single Instruction, Multiple Threads (SIMT) 的計算模型執行。每個線程束一次在其所有線程上發出一條指令,且每個線程都有自己的操作數。例如,如果一行著色器代碼添加兩個數字,則在一個線程束中,加法指令開始在所有 32 個線程中同時運行,從而從 64 個輸入中生成 32 個唯一的和。
線程束以次優方式運行的一種方法是通過著色器代碼中的 if 語句或控制流分支導致線程差異。編譯器可以通過在 if 語句下運行所有代碼塊,然后忽略未使用的結果,或使用展開的循環來完全避免分支。但是,當真正的動態分支被編譯下來并在執行時遇到時,并且條件表達式在線程束中的所有線程之間不是統一的,則線程束必須一次同時執行 if-body 和 else-body。
同樣,在 SIMT 模型中一次只能發出一條指令,因此 SM 必須屏蔽不適用于分支活動端的線程。有關現代 NVIDIA GPUs 中線程束指令調度的更完整說明,請參閱 NVIDIA Tesla V100 GPU 架構 (第 26 頁)。
圖 1 顯示了線程束中線程發散的簡化可視化,線程束的假設大小為 8 個線程。大寫字母表示程序偽代碼中的語句。由于發出每個指令時線程執行的空閑通道,吞吐量會降低。

請注意,這不同于前面提到的以無分支方式在 if 語句中運行兩個塊。真正的分支可以避免線程未執行的任何副作用。更重要的是,當驅動分支的條件表達式有良好的 warp 級分布時,動態分支可以成為制勝法。條件表達式得到的齊次結果越多,差異就越小,因此對吞吐量的影響就越小。在 vertex 和 pixel shaders 中, warp 會根據 locality of vertices 和 pixels 進行分組。在 ray tracing 和 compute shaders 中,用戶可以更明確地控制工作分組方式。
影響線程差異性能的其他因素包括任何分支下著色器指令的總體百分比,以及特定機器指令及其操作類型。了解實際影響的唯一方法是,在測量整體性能時能夠跟蹤 warp 線程效率,并關聯其中一個線程的變化。
這是新的 Active Threads per Warp 直方圖的用武之地。Nsight Graphics 的 GPU Trace 工具中的 Shader Profiler 視圖中現已提供此緊湊圖形,包括著色器工作流、自上而下、自下而上、熱點和源/反匯編。它說明了線程差異對任何給定著色器、函數或單個源代碼行的總體影響。
如圖 2 所示,直方圖右側的值 (接近 32) 表示指令執行效率更高。顯示的值根據執行每個代碼塊時的性能計數器采樣得出近似值。彈出工具提示會更詳細地顯示直方圖。當啟動 GPU Trace 時,必須將“Timeline Metrics”設置設置為“Top-Level Triage”或“Ray Tracing Triage”(如果可用),并啟用“Real-Time Shader Profiler”。

如果函數存在性能瓶頸,且每個線程束的活動線程數不足,則應考慮改進線程束一致性或減少分支的策略。有關光線追蹤工作負載,請參閱 Shader Execution Reordering(SER),它專為解決光線追蹤著色器中的線程和數據分散問題而設計。其他算法更改可能會提高線程執行的一致性;例如,使用不同的光線采樣模式。對于任何類型的著色器,還可以通過在 D3D12 或 Vulkan 中將分支轉換為線程束感知著色器代碼來提高效率。
直方圖的分布揭示了代碼塊的行為是否一致,并且查看每個線程束的活動線程數達到或接近 100% 也可能驗證線程發散不是最初被懷疑的限制因素。
圖 3 說明了路徑追蹤等高級照明技術如何在二次光線從場景中物體反彈時導致著色器發散。SER 提高了執行一致性,因為使用相同命中著色器的光線可以在線程束級別更好地利用 SIMT。當 SER 正常工作時,您應該會看到“Active Threads per Warp”得到改進。

在更高層次上,改善整體著色時間需要理解和減少 warp 失速。當 warp 達到長延遲運算時,尤其是內存訪問和紋理獲取等操作,會停止。當一個 warp 停止時,可以為下一個指令安排另一個 warp。但是,這只能購買如此多的并行性。如果過多的 warp 處于靜止狀態,則 SM 未得到充分利用,甚至會處于空閑狀態。延遲的長度取決于許多因素,例如內存查找所達到的緩存級別 (如果有)。
GPU Trace 一直提供用于分析這些延遲的工具,但箭袋中的新箭頭是 Warp Latency 直方圖,該直方圖以前曾作為單個平均 Warp Latency 周期計數呈現。通過觀察線程束延遲的分布情況,我們可以更深入地了解著色器計時的可變性,并提供提示,說明是否已提前退出,以及多次著色器調用的參數是否會導致不同的行為。請注意,直方圖目前僅包含調用同一著色器的時間軸中不相交區域的單獨延遲數據點。

有關優化 GPU 工作負載的更多詳細信息,請查看以下資源:
- 用于優化任何 GPU 工作負載的峰值性能百分比分析方法 描述了 NVIDIA 內部使用的一種性能分流方法,該方法使用 NVIDIA 特定的硬件指標來確定任何給定 GPU 工作負載的主要性能限制因素。
- 強大的著色器見解:使用著色器調試信息與 NVIDIA Nsight Graphics 結合使用 ,說明在編譯著色器時需要執行的步驟,以查看 GPU Trace 中的火焰圖形和源關聯。
- CUDA 編程指南 和 CUDA Refresher:CUDA 編程模型 介紹如何將計算和 SIMT 架構應用于圖形 API 中的計算著色器。
- NVIDIA Nsight Compute 簡介 – 一個 CUDA 內核分析器 以適用于圖形工作負載的方式討論 warp 調度。
D3D12 工作圖?
CPU 和 GPU 之間的交互通信是圖形管線中的另一個常見瓶頸。即使批量數據駐留在 GPU 上,從 CPU 發出渲染指令的行為也會在 GPU 處于空閑狀態時產生泡沫。工作圖是 D3D12 中的一項新功能,旨在減少調度 GPU 工作對 CPU 的依賴性。GPU 驅動的調度已經出現一段時間了,但工作圖形引入了比 ExecuteIndirect
等現有方法更先進的功能。有關工作圖形的概述,請參閱 Direct3D 12 中使用工作圖形推進 GPU 驅動渲染。
Nsight Graphics 2024.2 中引入了對 Shader Profiler 中分析 Work Graph 節點整體的初步支持。在 2024.3 中,Shader Profiler 現在支持 Work Graph 的源關聯,從而在 Shader Source 視圖和 Hot Spots 列表中啟用完整的逐行分析功能。由于 Work Graph 是 D3D12 中的一項新功能,因此此功能應能幫助開發者探索和更好地理解 Work Graph 的性能特征。請注意,源關聯需要最新的 R565 系列驅動。

同樣,Nsight Aftermath SDK 2024.3 增加了對用于跟蹤工作圖形的著色器的支持,并提供上下文信息,以幫助縮小源自工作圖形工作負載的相關 GPU 錯誤。
Vulkan 更新?
最近發布的 Vulkan 1.4 標準將十幾個先前可選擴展程序提升到所需的擴展程序集,并引入了更高的最低硬件限制。有關更多信息,請參閱 Khronos 簡化使用 Vulkan 1.4 的 GPU 加速應用程序的開發和部署 。Nsight Graphics 2024.3 在 Frame Debugger 中提供 Vulkan 1.4 支持。有關支持 1.4 的測試版驅動,請訪問 Vulkan 驅動支持 。
即使您未直接使用 Vulkan 1.4,Nsight Graphics 現在也支持所有新推廣的擴展。此外,還添加了對許多其他擴展程序的支持,包括 VK_NV_inherited_viewport_scissor 和 VK_NV_device_generated_commands_compute。有關完整列表,請參閱 NVIDIA Nsight Graphics 用戶指南 。
此版本還增加了對在 Windows 和 Linux 桌面平臺上使用 Vulkan SC 的應用程序的幀調試和 GPU 追蹤的支持。有關 Vulkan SC 和驅動支持的更多信息,請訪問 Vulkan 驅動支持 。
結束語?
在開始針對并行性進行優化之前,您可能需要對 GPU 計算模型有一個基本的了解。然而,由于數據模式、編譯器和硬件優化以及許多其他二階影響,該理論如何轉化為實踐可能很難預測。根據工具中的假設檢驗和測量記錄制定策略。了解指標的含義,然后在您進行調整時追蹤其變化情況。雖然同時實現 GPU 上每個硬件單元的 100%利用率并不切實際,但增量改進可以幫助您達到應用的性能需求。
Nsight Graphics 2024.3 現已推出 。使用位于 Nsight Graphics 窗口右上角的“Feedback”(反饋)按鈕,向我們介紹您使用這些新功能的體驗。
詳細了解 Nsight 開發者工具 并探索 Nsight Tools 教程 。在 Nsight Graphics Developer 論壇 上提問、提供反饋,以及與圖形開發者社區互動。
致謝?
感謝 Avinash Baliga、Jeff Kiel、Axel Mamode、Aurelio Reis 和 Louis Bavoil 為本文做出的貢獻。