Community程式設計與開發github.com

jiweibo/perf-nsight-compute-analysis

分析 ncu (NVIDIA Nsight Compute) 的效能分析輸出:SOL% 瓶頸分類、屋頂線分析、佔用率診斷、記憶體層級分析、warp 停頓分析、指標解讀,以及程式化的 .ncu-rep 報告分析。不適用於撰寫核心或生成程式碼、Nsight Systems (nsys)、主機端分析或系統層級分析。

perf-nsight-compute-analysis 是什麼?

此技能提供一套完整的系統化方法,用於分析 NVIDIA Nsight Compute (ncu) 的輸出,協助開發者找出 CUDA 核心的效能瓶頸並進行最佳化。它基於「光速 (SOL%)」指標,將瓶頸分類為計算密集型、記憶體密集型或延遲密集型,並提供對應的深入分析章節。技能支援從快速 SOL% 診斷到深入的多步驟工作流程 (包括屋頂線分析和驗證),並涵蓋 JIT 編譯核心 (如 Triton) 的分析技巧。此外,它提供程式化的 .ncu-rep 報告分析功能,利用 Python 的 ncu_report 模組,讓使用者能以自動化方式擷取指標、進行分類和報告。此技能特別強調資料完整性,要求每個數值結論都必須附有原始 ncu 輸出作為佐證,杜絕虛構資料。

相容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/jiweibo/skills/tree/HEAD/perf-nsight-compute-analysis

Installed? Explore more 程式設計與開發 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

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 GPUTuring+Volta 需要 Nsight Compute 2025.2 或更舊版本

權限:ncu 可能需要 sudo、CAP_SYS_ADMIN,或在容器內使用 --privileged。ncu -v 僅會顯示版本號碼;當分析第一個核心時,權限不足會顯示為 ERR_NVGPUCTRPERM。

原則

資料完整性

這是一個資料驅動的分析系統。您提出的每個數字都必須有權威來源。 請無例外地遵守以下規則:

  1. 先引用,後解釋。 在呈現 ncu 輸出的指標時,務必先顯示您實際執行的 ncu 指令以及相關的原始輸出 (CSV 行、指標值),然後再陳述任何數值結論。
  2. 絕不虛構指標。 如果 ncu 失敗、回傳非預期輸出,或您無法執行它,請明確說明。不要編造看起來合理的數字。誠實地說「分析失敗」勝過提供虛構的資料。
  3. 歸因每個數值。 您引用的每個指標 (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-6040-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:解讀與最佳化

  1. 從 SOL% 分類中找出主要瓶頸
  2. 在 references/bottleneck-guide.md 中查閱詳細分析和最佳化策略
  3. 優先應用影響最大的最佳化
  4. 重新分析以驗證改善情況並偵測瓶頸轉移

步驟 5:驗證

在最佳化後重新分析同一個核心:

ncu --section SpeedOfLight --csv \
    --kernel-name regex:"optimized_kernel" \
    --launch-count 3 \
    -- python optimized_script.py

比較:吞吐量百分比是否增加?持續時間是否減少?瓶頸類型是否改變?

分析 JIT 編譯核心 (Triton/cuTile/CuTeDSL)

JIT 編譯的核心會在首次呼叫時觸發自動調優。請隔離實際的執行:

  1. 先暖機:執行核心 3-5 次以完成 JIT 編譯和自動調優,然後執行 torch.cuda.synchronize()。
  2. 使用分析器標記:使用 cudaProfilerStart()/cudaProfilerStop() 將要量測的區域括起來。
  3. 使用 --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 NameSection意義
DurationSpeedOfLight執行時間
Compute (SM) ThroughputSpeedOfLight計算峰值的百分比
Memory ThroughputSpeedOfLight最忙碌記憶體單元峰值的百分比
SM FrequencySpeedOfLight分析執行時的時脈
Achieved OccupancyOccupancy活躍 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 快取命中率:低命中率表示...

... (後續內容依此類推,由於原文已截斷,翻譯也在此處截斷)

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

相關技能