O que Análise Nsight Compute faz?
O NVIDIA Nsight Compute (ncu) cria perfis de kernels CUDA individuais para determinar
por que eles são lentos e o que otimizar. Ele mede a taxa de transferência da GPU como uma
percentagem do pico teórico (Speed of Light / SOL%), permitindo classificação sistemática
de gargalos e otimização direcionada.
Quando Usar
Recorra a esta habilidade quando encontrar:
- Gatilhos: O usuário quer criar perfil de um kernel CUDA, analisar a saída
ncu, interpretar relatórios.ncu-rep, ou otimizar o desempenho do kernel da GPU - Sintomas: Kernel rodando mais lento que o esperado, baixa utilização da GPU, necessidade de classificar compute-bound vs memory-bound, problemas de ocupação
- Palavras-chave: "ncu", "nsight compute", "SOL%", "speed of light", "kernel profiling", "compute-bound", "memory-bound", "latency-bound", "occupancy", "roofline", "warp stalls", "cache hit rate", "ncu-rep"
NÃO use esta habilidade para:
- Perfilamento a nível de sistema (use Nsight Systems /
nsys) - Rastreamento de API CUDA ou análise de linha do tempo CPU-GPU (use
nsys) - Monitoramento de GPU sem perfilamento (use
nvidia-smi)
Requisitos
| Dependência | Versão | Notas |
|---|---|---|
| CUDA Toolkit | >=11.0 | Inclui ncu |
binário ncu | Suportado pelo driver | Nsight Compute 2026.3 precisa de um driver compatível com CUDA 13. Ou defina a variável de ambiente $NCU |
| GPU NVIDIA | Turing+ | Volta precisa do Nsight Compute 2025.2 ou mais antigo |
Permissões: ncu pode exigir sudo, CAP_SYS_ADMIN, ou --privileged
em contêineres. ncu -v apenas imprime a versão; permissão ausente aparece
como ERR_NVGPUCTRPERM quando o primeiro kernel é perfilado.
Princípios
Integridade dos Dados
Este é um sistema de análise orientado por dados. Cada número que você apresenta deve ter uma fonte autoritativa. Siga estas regras sem exceção:
- Cite antes de interpretar. Ao apresentar métricas da saída do ncu, sempre mostre o comando ncu real que você executou E a saída bruta relevante (linhas CSV, valores de métricas) antes de declarar qualquer conclusão numérica.
- Nunca invente métricas. Se o ncu falhar, retornar saída inesperada, ou você não conseguir executá-lo, diga isso explicitamente. Não invente números que pareçam plausíveis. Um "falha no perfilamento" honesto é melhor do que dados fabricados.
- Atribua cada valor. Para cada métrica que você citar (SOL%, duração, ocupação, taxa de transferência), o leitor deve ser capaz de rastreá-la de volta a uma linha específica na saída bruta do ncu que você mostrou.
Modelo Mental SOL%
Speed of Light (SOL%) mede o quão próximo um kernel roda do pico teórico da GPU:
- Compute SOL% (
Compute (SM) Throughput) = a taxa de transferência da unidade SM mais ocupada como % de seu pico - Memory SOL% (
Memory Throughput) = a taxa de transferência da unidade de memória mais ocupada (DRAM, L2, L1, memória compartilhada) como % de seu pico
A métrica mais alta geralmente revela o tipo de gargalo. Use isso como o sinal primário de classificação. Ambos podem estar altos ao mesmo tempo: o kernel está então próximo do limite de hardware para seu algoritmo.
Limiares de Classificação
| Compute % | Memory % | Gargalo | Próximo Passo |
|---|---|---|---|
| >60 | <40 | Compute-bound | Seção ComputeWorkloadAnalysis |
| <40 | >60 | Memory-bound | Seção MemoryWorkloadAnalysis |
| <40 | <40 | Latency-bound | Seções LaunchStats + Occupancy |
| 40-60 | 40-60 | Equilibrado | Perfilar mais profundamente com seções detalhadas |
| >60 | >60 | Próximo aos limites de hardware | Mudança algorítmica; verificar ambas as seções de carga de trabalho |
Sinais adicionais:
- Duração <10us com muitos lançamentos -> Limitado por overhead de lançamento (use nsys primeiro)
- Ambos <40% mas ocupação >50% -> Limitado por instrução (verifique InstructionStats)
Níveis de Desempenho SOL%
| SOL% | Nível | Ação |
|---|---|---|
| >80% | Excelente | Apenas ajustes menores |
| 60-80% | Bom | Otimização direcionada |
| 40-60% | Razoável | Otimização significativa necessária |
| <40% | Ruim | Grande reformulação necessária |
Perfilamento Orientado por Seção
Sempre use flags --section direcionadas em vez de coleta em massa --set. Seções individuais são mais rápidas e cirúrgicas. Apenasome para --set basic ou --set detailed quando uma exploração ampla for necessária.
ncu vs nsys
| Ferramenta | Escopo | Overhead | Propósito |
|---|---|---|---|
| nsys | Nível de sistema | 5-10% | Encontrar quais kernels otimizar |
| ncu | Nível de kernel | 10-100x mais lento | Entender por que um kernel é lento |
Use nsys primeiro para identificar os principais kernels por tempo de GPU, depois ncu para análise aprofundada desses kernels específicos.
Fluxo de Trabalho
Escolha seu caminho com base na solicitação:
- Consulta de conhecimento (quais métricas usar, --section vs --set, como filtrar kernels): Responda diretamente dos Princípios, Referência de Comandos e Referências abaixo. NÃO execute ncu.
- Diagnóstico rápido (classificar gargalo, verificar SOL%): Apenas Passo 1. Escale se o usuário quiser mais.
- Diagnóstico específico (conflitos de banco, pressão de registradores, ocupação): Verificação rápida de SOL% (Passo 1), depois vá diretamente para a seção relevante no Passo 2.
- Análise aprofundada (relatório detalhado, recomendações de otimização): Passos Completos 1-5. Apresente o relatório estruturado completo com todas as métricas principais (SOL%, duração, ocupação) em sua resposta final — não divida o relatório entre mensagens ou substitua-o por um resumo breve.
Passo 0: Verificar ncu
ncu -v
# Ou: $NCU -v
Se não for encontrado, certifique-se de que o CUDA toolkit está instalado ou defina a variável de ambiente NCU para o caminho do binário.
Passo 1: Diagnóstico SOL%
Sempre comece com SpeedOfLight para classificar o gargalo:
ncu --section SpeedOfLight --csv \
--kernel-name regex:"KERNEL" \
--launch-skip 5 --launch-count 3 \
-- COMMAND
Leia Compute (SM) Throughput e Memory Throughput da saída. Classifique usando os limiares acima.
Passo 2: Escalar com Seções Direcionadas
Com base na classificação do Passo 1, adicione seções:
| Classificação | Seções a Adicionar |
|---|---|
| Compute-bound | ComputeWorkloadAnalysis |
| Memory-bound | MemoryWorkloadAnalysis |
| Latency-bound | LaunchStats, Occupancy |
| Warp stalls | WarpStateStats, SchedulerStats |
| Precisa de detalhamento de instruções | InstructionStats |
Sempre inclua LaunchStats e Occupancy ao diagnosticar kernels com latência limitada. Elas revelam pressão de registradores, limites de memória compartilhada e problemas de tamanho de bloco.
Exemplo -- mergulho profundo em memory-bound:
ncu --section SpeedOfLight --section MemoryWorkloadAnalysis --csv \
--kernel-name regex:"embedding_lookup" \
--launch-count 3 \
-- python script.py
Exemplo -- mergulho profundo em compute-bound:
ncu --section SpeedOfLight --section ComputeWorkloadAnalysis --csv \
--kernel-name regex:"gemm|nvjet" \
--launch-count 3 -- python script.py
Exemplo -- investigação de ocupação:
ncu --section SpeedOfLight --section LaunchStats --section Occupancy --csv \
--kernel-name regex:"small_kernel" \
-- python script.py
Passo 3: Análise Roofline (Opcional)
Para entendimento visual do equilíbrio entre computação e memória. As seções roofline
são gráficos: no CLI elas imprimem apenas com --print-details all, que lista
os números por trás do gráfico (trabalho e tráfego alcançados e de pico). Para ver o
gráfico, salve um relatório com -o e abra-o na UI do Nsight Compute.
ncu --section SpeedOfLight_RooflineChart --print-details all \
--kernel-name regex:"KERNEL" -- COMMAND
Para roofline hierárquica específica de precisão:
# Kernels FP16
ncu --section SpeedOfLight_HierarchicalHalfRooflineChart --print-details all \
--kernel-name regex:"KERNEL" -- COMMAND
# Kernels de tensor core
ncu --section SpeedOfLight_HierarchicalTensorRooflineChart --print-details all \
--kernel-name regex:"KERNEL" -- COMMAND
Interpretação: kernel à esquerda do ponto de cumeeira = memory-bound; à direita = compute-bound;
muito abaixo de ambos os tetos = problema de latência/ocupação. Veja references/roofline-analysis.md.
Passo 4: Interpretar e Otimizar
- Identifique o gargalo dominante a partir da classificação SOL%
- Consulte análise detalhada e estratégias de otimização em
references/bottleneck-guide.md - Aplique a otimização de maior impacto primeiro
- Re-perfile para validar a melhoria e detectar mudanças de gargalo
Passo 5: Validar
Re-perfile o mesmo kernel após a otimização:
ncu --section SpeedOfLight --csv \
--kernel-name regex:"optimized_kernel" \
--launch-count 3 \
-- python optimized_script.py
Compare: A percentagem de taxa de transferência aumentou? A duração diminuiu? O tipo de gargalo mudou?
Perfilamento de Kernels Compilados JIT (Triton/cuTile/CuTeDSL)
Kernels compilados JIT acionam autotuning na primeira invocação. Isole a execução real:
- Aqueça primeiro: Execute o kernel 3-5 vezes para completar a compilação JIT e autotuning, depois
torch.cuda.synchronize(). - Use marcadores de profiler: Delimite a região medida com
cudaProfilerStart()/cudaProfilerStop(). - Use
--profile-from-start offpara que o ncu capture apenas a região marcada:
# Aquecimento (JIT + autotuning)
for _ in range(5):
result = kernel(inputs)
torch.cuda.synchronize()
# Perfilar apenas estado estacionário
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
Alternativa: use --launch-skip N para pular lançamentos de autotuning. Veja
references/advanced-profiling.md para alternativas de intervalo NVTX e modo de repetição.
Análise Programática de Relatórios
Extraia métricas de arquivos .ncu-rep ou .ncu-repz usando o módulo Python ncu_report
(em extras/python/ da instalação do Nsight Compute):
import ncu_report
ctx = ncu_report.load_report("report.ncu-rep")
for rng in ctx:
for action in rng:
name = action.name()
# "Compute (SM) Throughput" e "Memory Throughput" do SpeedOfLight
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)")
Veja references/python-report-api.md para a API completa (classes IContext, IRange, IAction, IMetric).
Formatos de Saída
Saída CSV (para scripting e análise automatizada):
ncu --csv --section SpeedOfLight --kernel-name regex:"KERNEL" -- COMMAND
ncu --csv --page raw --section SpeedOfLight -- COMMAND # Todas as métricas planas
O CSV padrão tem uma linha por métrica. Suas colunas incluem ID (o
lançamento perfilado), Kernel Name, Section Name, Metric Name, Metric Unit
e Metric Value; resultados de regras são linhas que preenchem Rule Name,
Rule Description e Estimated Speedup. Um Metric Name pode se repetir
entre seções (Memory Throughput é % no SpeedOfLight e byte/s no
MemoryWorkloadAnalysis), então filtre também por Section Name. --page raw dá uma
linha por lançamento, uma coluna por métrica e uma segunda linha de unidades. Os valores estão em
unidades base (ns, hz, %).
Durante o perfilamento, as linhas ==PROF== do ncu e a própria saída do aplicativo compartilham
o stdout com o CSV. Para CSV limpo, escreva um relatório e leia-o de volta:
Arquivos de relatório (para análise posterior):
ncu -o report.ncu-rep --section SpeedOfLight -- COMMAND
ncu --import report.ncu-rep --csv # Uma linha por métrica
ncu --import report.ncu-rep --csv --page raw # Uma linha por lançamento
Dê a -o a extensão: sem uma, Nsight Compute 2026.3 e mais recentes escrevem o
report.ncu-repz comprimido com zstd, e versões mais antigas escrevem report.ncu-rep.
--import e ncu_report leem ambos.
Linhas de métricas principais (valores de Metric Name):
| Metric Name | Section | Significado |
|---|---|---|
Duration | SpeedOfLight | Tempo de execução |
Compute (SM) Throughput | SpeedOfLight | % do pico de computação |
Memory Throughput | SpeedOfLight | % do pico da unidade de memória mais ocupada |
SM Frequency | SpeedOfLight | Clock em que o perfil foi executado |
Achieved Occupancy | Occupancy | Warps ativos / warps máximos (%) |
Indicadores de sucesso:
- Valores de SOL% presentes na saída -> perfilamento bem-sucedido
- Valores de duração razoáveis (não 0 ou extremamente grandes)
- Múltiplos lançamentos capturados quando
--launch-count > 1
Exemplos
Exemplo: Classificar um Kernel GEMM
Kernels cuBLAS GEMM em Blackwell são nomeados nvjet_*, então corresponda a ambos os nomes:
ncu --section SpeedOfLight --csv \
--kernel-name regex:"gemm|nvjet" \
--launch-skip 5 --launch-count 3 \
-- python train.py
Saída para uma multiplicação de matrizes FP16 4096x4096 em B200 (colunas e linhas abreviadas):
"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",
Interpretação: compute-bound (77.1% compute, 38.4% memória). Próximo passo:
verificar uso de tensor core com --section ComputeWorkloadAnalysis.
Exemplo: Diagnosticar um Kernel de Embedding com Memory-Bound
A busca de embedding do PyTorch executa vectorized_gather_kernel, então corresponda a ele também:
ncu --section SpeedOfLight --section MemoryWorkloadAnalysis --csv \
--kernel-name regex:"gather|index|embedding" \
--launch-count 3 -- python train.py
Verifique as taxas de acerto de cache L1/L2 na saída: baixas taxas de acerto