Nsight Compute 解析 は何をしますか?
NVIDIA Nsight Compute (ncu) は、個々の CUDA カーネルをプロファイリングし、なぜ遅いのか、何を最適化すべきかを特定します。GPU スループットを理論ピークに対するパーセンテージ(Speed of Light / SOL%)として測定し、体系的なボトルネック分類とターゲットを絞った最適化を可能にします。
使用すべき状況
以下のような状況に遭遇した場合にこのスキルを使用します。
- トリガー: CUDA カーネルをプロファイリングしたい、
ncuの出力を解析したい、.ncu-repレポートを解釈したい、GPU カーネルのパフォーマンスを最適化したい - 症状: カーネルが予想よりも遅い、GPU 使用率が低い、計算バウンドかメモリバウンドかを分類する必要がある、占有率に問題がある
- キーワード:
ncu,nsight compute,SOL%,speed of light、カーネルプロファイリング、compute-bound、memory-bound、latency-bound、occupancy、ルーフライン、warp stall、キャッシュヒット率、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% メンタルモデル
Speed of Light (SOL%) は、カーネルが GPU の理論ピークにどれだけ近いかを測定します。
- Compute SOL% (
Compute (SM) Throughput) = 最もビジーな SM ユニットのスループットのピークに対する割合 - Memory SOL% (
Memory Throughput) = 最もビジーなメモリユニット(DRAM、L2、L1、共有メモリ)のスループットのピークに対する割合
通常、高い方のメトリクスがボトルネックの種類を示します。これを主要な分類シグナルとして使用します。両方が同時に高い場合、カーネルはそのアルゴリズムのハードウェア限界に近づいています。
分類の閾値
| Compute % | Memory % | ボトルネック | 次のステップ |
|---|---|---|---|
| >60 | <40 | Compute-bound | ComputeWorkloadAnalysis セクション |
| <40 | >60 | Memory-bound | MemoryWorkloadAnalysis セクション |
| <40 | <40 | Latency-bound | LaunchStats + Occupancy セクション |
| 40-60 | 40-60 | Balanced | 詳細セクションでさらに深くプロファイリング |
| >60 | >60 | ハードウェア限界に近い | アルゴリズムの変更; 両方のワークロードセクションを確認 |
追加シグナル:
- 実行時間 <10us で起動回数が多い -> 起動オーバーヘッドバウンド(最初に nsys を使用)
- 両方が <40% で占有率 >50% -> 命令バウンド(InstructionStats を確認)
SOL% パフォーマンスレベル
| SOL% | レベル | アクション |
|---|---|---|
| >80% | 優秀 | マイナーチューニングのみ |
| 60-80% | 良好 | ターゲットを絞った最適化 |
| 40-60% | 普通 | 大幅な最適化が必要 |
| <40% | 不良 | 大規模な再設計が必要 |
セクションファーストプロファイリング
常に一括の --set 収集ではなく、ターゲットを絞った --section フラグを使用します。個別のセクションはより高速で、より的確です。広範な探索が必要な場合にのみ --set basic または --set detailed にエスカレーションします。
ncu と nsys の比較
| ツール | 範囲 | オーバーヘッド | 目的 |
|---|---|---|---|
| nsys | システムレベル | 5-10% | 最適化すべきカーネルを見つける |
| ncu | カーネルレベル | 10-100倍遅い | カーネルが遅い理由を理解する |
まず nsys を使用して GPU 時間が長いトップカーネルを特定し、その後 ncu を使用してそれらの特定のカーネルを詳細に分析します。
ワークフロー
リクエストに応じて適切なパスを選択します:
- 知識クエリ(使用するメトリクス、--section vs --set、カーネルのフィルタリング方法): 以下の原則、コマンドリファレンス、リファレンスから直接回答します。ncu を実行しません。
- クイック診断(ボトルネックの分類、SOL% の確認): ステップ 1 のみ。ユーザーがさらに求めればエスカレーションします。
- 特定診断(バンクコンフリクト、レジスタプレッシャー、占有率): クイック SOL% 確認(ステップ 1)、その後ステップ 2 の関連セクションに直接進みます。
- 詳細分析(詳細レポート、最適化推奨): ステップ 1〜5 をすべて実行します。最終応答には、すべての主要メトリクス(SOL%、実行時間、占有率)を含む完全な構造化レポートを提示します。レポートを複数のメッセージに分割したり、簡単な要約で置き換えたりしないでください。
ステップ 0: ncu の確認
ncu -v
# または: $NCU -v
見つからない場合、CUDA ツールキットがインストールされていることを確認するか、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 の分類に基づいて、セクションを追加します。
| 分類 | 追加するセクション |
|---|---|
| Compute-bound | ComputeWorkloadAnalysis |
| Memory-bound | MemoryWorkloadAnalysis |
| Latency-bound | LaunchStats, Occupancy |
| Warp stall | 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)")
完全な API(IContext, IRange, IAction, IMetric クラス)については references/python-report-api.md を参照してください。
出力形式
CSV 出力(スクリプトおよび自動分析用):
ncu --csv --section SpeedOfLight --kernel-name regex:"KERNEL" -- COMMAND
ncu --csv --page raw --section SpeedOfLight -- COMMAND # すべてのメトリクスをフラットに
デフォルトの CSV にはメトリクスごとに 1 行が含まれます。その列には ID(プロファイリングされた起動)、Kernel Name、Section Name、Metric Name、Metric Unit、Metric Value が含まれます。ルール結果は Rule Name、Rule Description、Estimated Speedup を埋める行です。Metric Name はセクション間で繰り返される可能性があるため(Memory Throughput は SpeedOfLight では %、MemoryWorkloadAnalysis では バイト/秒)、Section Name でもフィルタリングします。--page raw は起動ごとに 1 行、メトリクスごとに 1 列、および 2 行目の単位を提供します。値は基本単位(ns、hz、%)です。
プロファイリング中、ncu の ==PROF== 行とアプリケーション自身の出力は CSV と stdout を共有します。クリーンな CSV を得るには、レポートを書き込んでから読み戻します。
レポートファイル(後続の分析用):
ncu -o report.ncu-rep --section SpeedOfLight -- COMMAND
ncu --import report.ncu-rep --csv # メトリクスごとに 1 行
ncu --import report.ncu-rep --csv --page raw # 起動ごとに 1 行
-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 | アクティブワープ / 最大ワープ (%) |
成功の指標:
- 出力に 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",
解釈: compute-bound (77.1% 計算、38.4% メモリ)。次のステップ: --section ComputeWorkloadAnalysis でテンソルコアの使用状況を確認します。
例: メモリバウンドの埋め込みカーネルの診断
PyTorch の埋め込みルックアップは vectorized_gather_kernel を実行するため、それもマッチさせます。
ncu --section SpeedOfLight --section MemoryWorkloadAnalysis --csv \
--kernel-name regex:"gather|index|embedding" \
--launch-count 3 -- python train.py
出力の L1/L2 キャッシュヒット率を確認します。ヒット率が低い場合、データの局所性が悪いか、メモリアクセスパターンが非効率であることを示します。
例: レイテンシバウンドカーネルの診断
ncu --section SpeedOfLight --section LaunchStats --section Occupancy --csv \
--kernel-name regex:"small_kernel" \
-- python script.py
LaunchStats の registers_per_thread、shared_mem_per_block、max_threads_per_block の値を確認します。これらはレジスタプレッシャーとブロックサイズの制限を明らかにします。
例: ワープストール分析
ncu --section WarpStateStats --csv \
--kernel-name regex:"KERNEL" \
-- python script.py
長時間の long_scoreboard ストールはメモリアクセス待機を示し、short_scoreboard は算術依存関係を示し、not_selected は命令発行のボトルネックを示します。
コマンドリファレンス
| フラグ | 説明 | 例 |
|---|---|---|
--section <名前> | 特定の分析セクションを含める | --section SpeedOfLight |
--set <basic/detailed/full> | セクションのグループを含める | --set basic |
--kernel-name regex:<パターン> | カーネル名でフィルタリング(正規表現) | `--kernel-name regex:"matmul |
--kernel-name basename:<名前> | カーネル名のベース名でフィルタリング | --kernel-name basename:matmul_kernel |
--launch-skip N | 最初の N 回のカーネル起動をスキップ | --launch-skip 5 |
--launch-count N | N 回のカーネル起動をプロファイリング | --launch-count 3 |
--launch-num N | 特定の起動をプロファイリング(0 から開始) | --launch-num 1 |
--csv | CSV 形式で出力 | ncu --csv [...] |
--page raw | メトリクスを行ではなく列として出力(CSV と併用) | ncu --csv --page raw |
--print-details all | チャートの数値データを含むすべての詳細を表示 | ncu --print-details all [...] |
-o <ファイル> | レポートをファイルに保存 | ncu -o report.ncu-rep [...] |
--import <ファイル> | 保存されたレポートを読み込み、別の形式で出力 | ncu --import report.ncu-rep --csv |
--profile-from-start off | ncu を一時停止状態で開始し、後で cudaProfilerStart で再開 | --profile-from-start off |
--target-processes all | すべてのプロセス(子プロセスを含む)をプロファイリング | --target-processes all |
--replay-mode <application/kernel> | リプレイモードを設定(アプリケーションは各起動の前後に状態をリセット、カーネルは ncu が自動的に再現) | --replay-mode kernel |
--nvtx / --nvtx-include / --nvtx-exclude | NVTX 範囲でプロファイリングをフィルタリング | --nvtx-include "training_loop" |
リファレンス
分析中に以下のリファレンスドキュメントを参照してください。
references/bottleneck-guide.md: 各ボトルネックタイプ(計算、メモリ、レイテンシ)の詳細な診断と最適化戦略references/roofline-analysis.md: ルーフラインチャートの解釈方法の詳細references/advanced-profiling.md: NVTX 範囲、リプレイモード、複数 GPU の設定references/python-report-api.md: 完全な ncu_report Python APIreferences/metric-catalog.md: プロファイリング可能な全メトリクス(ハードウェアカウンター別に整理)