Nsight Compute 分析
NVIDIA Nsight Compute (ncu) 會對個別的 CUDA 核心進行分析,以判斷其執行緩慢的原因及最佳化方向。它會將 GPU 的吞吐量量測為理論峰值 (光速 / SOL%) 的百分比,從而實現系統化的瓶頸分類和目標導向的最佳化。
使用時機
當遇到以下情況時,請使用此技能:
- 觸發條件:使用者想要分析 CUDA 核心、解讀
ncu輸出、解析.ncu-rep報告,或最佳化 GPU 核心效能。 - 症狀:核心執行速度比預期慢、GPU 使用率低、需要分類是計算密集型還是記憶體密集型、佔用率問題。
- 關鍵字:「ncu」、「nsight compute」、「SOL%」、「speed of light」、「核心分析」、「計算密集型」、「記憶體密集型」、「延遲密集型」、「佔用率」、「屋頂線」、「warp 停頓」、「快取命中率」、「ncu-rep」
請勿將此技能用於:
- 系統層級分析 (請改用 Nsight Systems /
nsys) - CUDA API 追蹤或 CPU-GPU 時間軸分析 (請改用
nsys) - 未進行分析的 GPU 監控 (請改用
nvidia-smi)
需求
| 依賴項 | 版本 | 備註 |
|---|---|---|
| CUDA Toolkit | >=11.0 | 包含 ncu |
ncu 二進位檔 | 驅動程式支援的版本 | Nsight Compute 2026.3 需要與 CUDA 13 相容的驅動程式。或設定 $NCU 環境變數 |
| NVIDIA GPU | Turing+ | Volta 需要 Nsight Compute 2025.2 或更舊版本 |
權限:ncu 可能需要 sudo、CAP_SYS_ADMIN,或在容器內使用 --privileged。ncu -v 僅會顯示版本號碼;當分析第一個核心時,權限不足會顯示為 ERR_NVGPUCTRPERM。
原則
資料完整性
這是一個資料驅動的分析系統。您提出的每個數字都必須有權威來源。 請無例外地遵守以下規則:
- 先引用,後解釋。 在呈現 ncu 輸出的指標時,務必先顯示您實際執行的 ncu 指令以及相關的原始輸出 (CSV 行、指標值),然後再陳述任何數值結論。
- 絕不虛構指標。 如果 ncu 失敗、回傳非預期輸出,或您無法執行它,請明確說明。不要編造看起來合理的數字。誠實地說「分析失敗」勝過提供虛構的資料。
- 歸因每個數值。 您引用的每個指標 (SOL%、持續時間、佔用率、吞吐量),讀者都必須能夠追溯到您所顯示的原始 ncu 輸出中的特定行。
SOL% 心智模型
光速 (SOL%) 用於衡量核心運算接近 GPU 理論峰值的程度:
- 計算 SOL% (
Compute (SM) Throughput) = 最忙碌的 SM 單元吞吐量佔其峰值的百分比 - 記憶體 SOL% (
Memory Throughput) = 最忙碌的記憶體單元 (DRAM、L2、L1、共享記憶體) 吞吐量佔其峰值的百分比
通常較高的指標會揭示瓶頸類型,並將其作為主要的分類信號。兩者可能同時偏高:此時核心已接近其演算法的硬體極限。
分類閾值
| 計算 % | 記憶體 % | 瓶頸 | 下一步 |
|---|---|---|---|
| >60 | <40 | 計算密集型 | ComputeWorkloadAnalysis 章節 |
| <40 | >60 | 記憶體密集型 | MemoryWorkloadAnalysis 章節 |
| <40 | <40 | 延遲密集型 | LaunchStats + Occupancy 章節 |
| 40-60 | 40-60 | 平衡型 | 使用詳細章節進行更深層分析 |
| >60 | >60 | 接近硬體極限 | 演算法層面變更;檢查兩個工作負載章節 |
其他信號:
- 持續時間 <10us 且有大量啟動 -> 啟動開銷密集型 (請先使用 nsys)
- 兩者皆 <40% 但佔用率 >50% -> 指令密集型 (請檢查 InstructionStats)
SOL% 效能等級
| SOL% | 等級 | 行動 |
|---|---|---|
| >80% | 極佳 | 僅需微調 |
| 60-80% | 良好 | 目標導向最佳化 |
| 40-60% | 普通 | 需要重大最佳化 |
| <40% | 不佳 | 需要大幅重做 |
先章節後分析
請優先使用 --section 標記進行目標導向收集,而非使用 --set 進行大量收集。個別章節更快且更有針對性。僅在需要廣泛探索時,才升級至 --set basic 或 --set detailed。
ncu vs nsys
| 工具 | 範圍 | 開銷 | 目的 |
|---|---|---|---|
| nsys | 系統層級 | 5-10% | 找出需要最佳化的核心 |
| ncu | 核心層級 | 慢 10-100 倍 | 了解核心為何執行緩慢 |
請先使用 nsys 找出 GPU 時間最長的核心,再使用 ncu 對這些特定核心進行深入分析。
工作流程
根據請求選擇您的路徑:
- 知識查詢 (該使用哪些指標、
--section與--set的比較、如何過濾核心): 直接從下方的原則、指令參考和參考資料中回答。請勿執行 ncu。 - 快速診斷 (分類瓶頸、檢查 SOL%):僅進行步驟 1。若使用者需要更多資訊才升級。
- 特定診斷 (銀行衝突、暫存器壓力、佔用率):快速執行 SOL% 檢查 (步驟 1), 然後直接前往步驟 2 的相關章節。
- 深入分析 (詳細報告、最佳化建議):完整執行步驟 1-5。 請在最終回覆中呈現完整的結構化報告,包含所有關鍵指標 (SOL%、持續時間、 佔用率) — 請勿將報告分散在多則訊息中,或僅提供簡短摘要。
步驟 0:驗證 ncu
ncu -v
# 或:$NCU -v
如果找不到,請確保已安裝 CUDA toolkit,或將 NCU 環境變數設為二進位檔案路徑。
步驟 1:SOL% 診斷
請始終從 SpeedOfLight 開始,以分類瓶頸:
ncu --section SpeedOfLight --csv \
--kernel-name regex:"KERNEL" \
--launch-skip 5 --launch-count 3 \
-- COMMAND
從輸出中讀取 Compute (SM) Throughput 和 Memory Throughput。使用上述閾值進行分類。
步驟 2:使用目標章節升級
根據步驟 1 的分類結果,添加章節:
| 分類 | 要添加的章節 |
|---|---|
| 計算密集型 | ComputeWorkloadAnalysis |
| 記憶體密集型 | MemoryWorkloadAnalysis |
| 延遲密集型 | LaunchStats, Occupancy |
| Warp 停頓 | WarpStateStats, SchedulerStats |
| 需要指令分解 | InstructionStats |
診斷延遲密集型核心時,請務必包含 LaunchStats 和 Occupancy。這些章節能揭示暫存器壓力、共享記憶體限制和區塊大小問題。
範例 — 記憶體密集型深入分析:
ncu --section SpeedOfLight --section MemoryWorkloadAnalysis --csv \
--kernel-name regex:"embedding_lookup" \
--launch-count 3 \
-- python script.py
範例 — 計算密集型深入分析:
ncu --section SpeedOfLight --section ComputeWorkloadAnalysis --csv \
--kernel-name regex:"gemm|nvjet" \
--launch-count 3 -- python script.py
範例 — 佔用率調查:
ncu --section SpeedOfLight --section LaunchStats --section Occupancy --csv \
--kernel-name regex:"small_kernel" \
-- python script.py
步驟 3:屋頂線分析 (選擇性)
用於視覺化理解計算與記憶體的平衡。屋頂線章節是圖表:在 CLI 上,它們僅在使用 --print-details all 時才會列印,該選項會列出圖表背後的數值 (已達成和峰值的工作量與流量)。若要查看圖表,請使用 -o 儲存報告,並在 Nsight Compute UI 中開啟。
ncu --section SpeedOfLight_RooflineChart --print-details all \
--kernel-name regex:"KERNEL" -- COMMAND
針對特定精度的階層式屋頂線:
# FP16 核心
ncu --section SpeedOfLight_HierarchicalHalfRooflineChart --print-details all \
--kernel-name regex:"KERNEL" -- COMMAND
# Tensor core 核心
ncu --section SpeedOfLight_HierarchicalTensorRooflineChart --print-details all \
--kernel-name regex:"KERNEL" -- COMMAND
解讀:核心位於脊點左側 = 記憶體密集型;右側 = 計算密集型;遠低於兩條屋頂線 = 延遲/佔用率問題。請參閱 references/roofline-analysis.md。
步驟 4:解讀與最佳化
- 從 SOL% 分類中找出主要瓶頸
- 在
references/bottleneck-guide.md中查閱詳細分析和最佳化策略 - 優先應用影響最大的最佳化
- 重新分析以驗證改善情況並偵測瓶頸轉移
步驟 5:驗證
在最佳化後重新分析同一個核心:
ncu --section SpeedOfLight --csv \
--kernel-name regex:"optimized_kernel" \
--launch-count 3 \
-- python optimized_script.py
比較:吞吐量百分比是否增加?持續時間是否減少?瓶頸類型是否改變?
分析 JIT 編譯核心 (Triton/cuTile/CuTeDSL)
JIT 編譯的核心會在首次呼叫時觸發自動調優。請隔離實際的執行:
- 先暖機:執行核心 3-5 次以完成 JIT 編譯和自動調優,然後執行
torch.cuda.synchronize()。 - 使用分析器標記:使用
cudaProfilerStart()/cudaProfilerStop()將要量測的區域括起來。 - 使用
--profile-from-start off,讓 ncu 僅捕捉標記的區域:
# 暖機 (JIT + 自動調優)
for _ in range(5):
result = kernel(inputs)
torch.cuda.synchronize()
# 僅分析穩定狀態
torch.cuda.cudart().cudaProfilerStart()
for _ in range(3):
result = kernel(inputs)
torch.cuda.synchronize()
torch.cuda.cudart().cudaProfilerStop()
ncu --profile-from-start off --section SpeedOfLight --csv \
--kernel-name regex:"target_kernel" \
--launch-count 3 -- python script.py
替代方案:使用 --launch-skip N 跳過自動調優啟動。有關 NVTX 範圍和重播模式的替代方案,請參閱 references/advanced-profiling.md。
程式化報告分析
使用 ncu_report Python 模組 (位於 Nsight Compute 安裝目錄的 extras/python/) 從 .ncu-rep 或 .ncu-repz 檔案中提取指標:
import ncu_report
ctx = ncu_report.load_report("report.ncu-rep")
for rng in ctx:
for action in rng:
name = action.name()
# SpeedOfLight 的 "Compute (SM) Throughput" 和 "Memory Throughput"
compute = action["sm__throughput.avg.pct_of_peak_sustained_elapsed"].as_double()
memory = action["gpu__compute_memory_throughput.avg.pct_of_peak_sustained_elapsed"].as_double()
duration = action["gpu__time_duration.sum"].as_uint64()
if compute > 60:
classification = "compute-bound"
elif memory > 60:
classification = "memory-bound"
else:
classification = "latency-bound"
print(f"{name}: {classification} (compute={compute:.1f}%, mem={memory:.1f}%, {duration}ns)")
請參閱 references/python-report-api.md 以取得完整的 API (IContext, IRange, IAction, IMetric 類別)。
輸出格式
CSV 輸出 (適用於腳本化和自動化分析):
ncu --csv --section SpeedOfLight --kernel-name regex:"KERNEL" -- COMMAND
ncu --csv --page raw --section SpeedOfLight -- COMMAND # 所有指標展平
預設的 CSV 每個指標有一行。其欄位包含 ID (被分析的啟動)、Kernel Name、Section Name、Metric Name、Metric Unit 和 Metric Value;規則結果則是以填入 Rule Name、Rule Description 和 Estimated Speedup 的行呈現。一個 Metric Name 可能會跨章節重複 (Memory Throughput 在 SpeedOfLight 中是百分比,在 MemoryWorkloadAnalysis 中是 byte/s),因此也需要同時根據 Section Name 進行過濾。--page raw 會為每次啟動產生一行,每個指標一欄,以及第二行的單位。數值使用基本單位 (ns、hz、%)。
在分析時,ncu 的 ==PROF== 行和應用程式本身的輸出會與 CSV 共享標準輸出。若要取得乾淨的 CSV,請先寫入報告再讀取回來:
報告檔案 (適用於後續分析):
ncu -o report.ncu-rep --section SpeedOfLight -- COMMAND
ncu --import report.ncu-rep --csv # 每個指標一行
ncu --import report.ncu-rep --csv --page raw # 每次啟動一行
使用 -o 時請提供副檔名:若無副檔名,Nsight Compute 2026.3 及更新版本會寫入 zstd 壓縮的 report.ncu-repz,而較舊版本則會寫入 report.ncu-rep。--import 和 ncu_report 都能讀取這兩種格式。
關鍵指標行 (Metric Name 值):
| Metric Name | Section | 意義 |
|---|---|---|
Duration | SpeedOfLight | 執行時間 |
Compute (SM) Throughput | SpeedOfLight | 計算峰值的百分比 |
Memory Throughput | SpeedOfLight | 最忙碌記憶體單元峰值的百分比 |
SM Frequency | SpeedOfLight | 分析執行時的時脈 |
Achieved Occupancy | Occupancy | 活躍 warp / 最大 warp (%) |
成功指標:
- 輸出中存在 SOL% 數值 -> 分析成功
- Duration 數值合理 (非 0 或極大值)
- 當
--launch-count > 1時捕捉到多次啟動
範例
範例:分類一個 GEMM 核心
Blackwell 上的 cuBLAS GEMM 核心名稱是 nvjet_*,因此請同時匹配兩個名稱:
ncu --section SpeedOfLight --csv \
--kernel-name regex:"gemm|nvjet" \
--launch-skip 5 --launch-count 3 \
-- python train.py
B200 上 FP16 4096x4096 矩陣乘法的輸出 (欄位與行已簡化):
"ID",...,"Kernel Name",...,"Section Name","Metric Name","Metric Unit","Metric Value",...
"0",...,"nvjet_sm100_hsh_128x256_64x6_2x2f_2cta_h_bz_NNT",...,"GPU Speed Of Light Throughput","Memory Throughput","%","38.38",
"0",...,"nvjet_sm100_hsh_128x256_64x6_2x2f_2cta_h_bz_NNT",...,"GPU Speed Of Light Throughput","Duration","ns","97600",
"0",...,"nvjet_sm100_hsh_128x256_64x6_2x2f_2cta_h_bz_NNT",...,"GPU Speed Of Light Throughput","Compute (SM) Throughput","%","77.11",
解讀:計算密集型 (計算 77.1%,記憶體 38.4%)。下一步:使用 --section ComputeWorkloadAnalysis 檢查 tensor core 使用情況。
範例:診斷一個記憶體密集型的 Embedding 核心
PyTorch 的 embedding lookup 會執行 vectorized_gather_kernel,因此請一併匹配它:
ncu --section SpeedOfLight --section MemoryWorkloadAnalysis --csv \
--kernel-name regex:"gather|index|embedding" \
--launch-count 3 -- python train.py
在輸出中檢查 L1/L2 快取命中率:低命中率表示...
... (後續內容依此類推,由於原文已截斷,翻譯也在此處截斷)