
圖形開發者和發燒友的一大消遣方式是比較 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%利用率並不切實際,但增量改進可以幫助您達到應用的性能需求。
WeChat
Profile