- Parte da ausência de um depurador capaz de pausar a execução da GPU e inspecionar seu estado e explica o processo de implementar isso diretamente em GPUs AMD
- Comunica-se diretamente com a GPU por meio da interface DRM e do libdrm, montando passo a passo o processo de criação de contexto, alocação de buffers e envio de comandos
- Usa os registradores TBA/TMA e um trap handler para interromper a execução da GPU, construindo uma estrutura para ler e restaurar o estado por meio de sincronização com a CPU
- Expande para um ambiente real de depuração de shaders por meio de compilação de código SPIR-V e integração com o RADV, tornando possível implementar breakpoint, stepping e watchpoint
- Essa abordagem, que controla diretamente a estrutura interna da GPU, demonstra a viabilidade de implementar um depurador completo para GPUs AMD e abre espaço para futura evolução com integração ao Vulkan
Necessidade e abordagem para depuração de GPU
- Parte da falta de ferramentas que permitam pausar a execução da GPU e inspecionar seu estado, como acontece na CPU
- O modelo de execução paralela da GPU torna a depuração muito mais complexa
- Existe o
rocgdb no ambiente AMD ROCm, mas ele oferece suporte limitado ao ROCm
- Com base na série de posts do blog de Marcell Kiss, tenta-se implementar um depurador que se comunica diretamente com a GPU
Comunicação direta com a GPU
- Aprende-se a forma de comunicação direta com a GPU acompanhando o funcionamento do driver RADV
- Abre
/dev/dri/cardX, conecta-se ao KMD (driver em modo kernel) e depois chama amdgpu_device_initialize
- Por meio do
libdrm, realiza criação de contexto (amdgpu_cs_ctx_create) e alocação de buffers
- São criados dois buffers: um de código e um de comandos
- Os buffers são mapeados no espaço de endereços virtuais da GPU/CPU
- Em vez de
amdgpu_bo_va_op, o mapeamento é feito com chamadas IOCTL diretas
- Usa
clang e objdump para compilar código assembly de shader e extrair o binário
- Monta comandos da GPU no formato PM4 Packet para enviar a execução do shader
Traps da GPU e uso de Debugfs
- Configura um trap handler usando os registradores TBA/TMA da ISA RDNA3
TBA: endereço do trap handler
TMA: endereço de memória temporária para o trap handler
- Como o acesso direto não é possível no espaço do usuário, usa a interface debugfs
- Acessa registradores pelo arquivo
/sys/kernel/debug/dri/{PCI address}/regs2
- Faz escrita em registradores com
amdgpu_debugfs_regs2_write
- Define TBA/TMA por VMID para ativar o trap handler
- Cada VMID distingue um contexto de processo da GPU
Implementação do trap handler
- O trap handler é um programa de shader privilegiado executado quando a GPU encontra uma exceção
- Usa registradores TTMP para salvar o estado da GPU (STATUS, EXEC, VCC etc.)
- A instrução
global_store_addtid_b32 é usada para gravar em memória os valores de registradores por thread
- Quando a GPU grava os dados, a CPU detecta isso e pausa temporariamente a GPU com o registrador SQ_CMD
- Depois de analisar os dados, a CPU usa novamente
SQ_CMD para retomar a execução da GPU
- Ao retornar, o trap handler restaura o contador de programa e o estado dos registradores
Execução de código SPIR-V e integração com o RADV
- Passa a oferecer suporte à compilação de código SPIR-V em vez de assembly manual
- Usa o compilador
ACO do RADV para converter SPIR-V em binário de GPU
- Cria um dispositivo virtual com a variável de ambiente
RADV_FORCE_FAMILY
- No modo
null_winsys do RADV, realiza apenas a compilação sem acessar hardware real
- Do resultado da compilação, extrai código de shader, configuração de recursos e informações de depuração
Expansão dos recursos do depurador
- Stepping: usa os bits
RSRC1.DEBUG_MODE e RSRC3.TRAP_ON_START para controlar a execução no nível de instrução
- Breakpoints: processa traps após calcular a posição do contador de programa com base no endereço do buffer de código
- Source Mapping: faz mapeamento para linhas do código-fonte com as informações de depuração do compilador ACO
- Watchpoints: é possível implementar monitoramento de endereços com proteção de página da GPU ou com o registrador
SQ_WATCH
- Rastreamento de nomes e tipos de variáveis: é necessário melhorar a propagação das informações de depuração na etapa de otimização NIR do Mesa
- Integração com Vulkan: com base no RADV, é possível fazer depuração por frame e aproveitar informações de buffers, texturas e constantes
Bônus: código de page walking em modo usuário
- Fornece um exemplo de código para percorrer tabelas de páginas para GPUs RDNA3 (gfx11)
- Inclui definições de estruturas PDE/PTE e funções de decodificação
- Implementa o processo de conversão de endereços virtuais em endereços físicos
- Ao ler registradores de tabela de páginas por VMID, torna-se possível analisar a estrutura de mapeamento de memória da GPU
Conclusão
- Demonstra a viabilidade de implementar um depurador completo para GPUs AMD por meio de acesso em nível de kernel e hardware
- Constrói um loop de comunicação bidirecional entre CPU e GPU para realizar pausa de execução, análise de estado e retomada
- No futuro, há potencial para evoluir para um ambiente de depuração de GPU mais amigável para desenvolvedores com integração ao RADV e ao Vulkan
1 comentários
Comentários do Hacker News
Não é da AMD, mas o Metal oferece um conjunto realmente excelente de depuradores e ferramentas de desenvolvimento
Por isso, quando trabalho com GPU, sempre prefiro usar Metal primeiro e depois portar para outros sistemas
Vale a pena consultar a documentação do Metal Debugger
Não sou desenvolvedor de jogos AAA, mas para o meu uso ele foi quase perfeito
Fiquei especialmente impressionado com o recurso de imprimir strings de log formatadas a partir do shader e vê-las misturadas com os logs do app
Estou desenvolvendo um app baseado em GPU que usa tanto Metal quanto OpenGL, e no lado do OpenGL foi difícil encontrar ferramentas no nível do Metal
As duas plataformas oferecem depuradores dedicados, e a qualidade deles era muito boa
No fim, percebi que quando tudo o que aparece é uma tela preta, tooling é tudo
Fico curioso se usar DirectX em vez de OpenGL daria acesso a ferramentas melhores no Windows
Especialmente ao lidar com compute shaders, muitas vezes o profiling não funciona direito
Como é uma ferramenta pensada com foco em gráficos, parece ainda ter limitações para IA ou trabalho com buffers grandes
Funcionou muito melhor para mim do que OpenGL
No lado do OpenGL, você já experimentou o RenderDoc? Para Vulkan/OpenGL, é a ferramenta mais parecida
Comprar um computador caro para depurar uma API exclusiva do Metal é ineficiente
Se a ideia é aprender programação gráfica a sério, acho melhor estudar DX12 ou Vulkan no Windows ou Linux
Com ferramentas como o RenderDoc, isso é totalmente viável
Metal é uma boa API, mas sua maior limitação é não poder ser usada fora das plataformas da Apple
Em servidores ou no ambiente de jogos, a maioria usa GPUs AMD ou Nvidia, então desenvolvimento centrado em Metal não é muito prático
O CUDA da NVIDIA tem um GDB oficial chamado cuda-gdb
Como dá para ver na documentação oficial, ele se encaixa bem no modelo de threads do CUDA
Mas só permite executar passo a passo no nível de warp
Em placas da NVIDIA, dá para usar o NSight, e também existe o RenderDoc, que funciona em várias GPUs
Quando faltam visualizações de alto nível como QML ou QSG_VISUALIZE=overdraw, é interessante rastrear a cena no nível das chamadas de API
Muita gente não sabe que elas podem ser usadas mesmo sem GPU
Sobre a pergunta se há ferramentas oficiais para AMD: o GDB oferece suporte a depuração de GPU AMD
Além disso, existem ferramentas da AMD como UMR,
Radeon GPU Detective e
Radeon Developer Tool Suite
Compartilhando uma ferramenta de monitoramento feita por mim para GPUs AMD
É um projeto chamado picomon, criado para resolver o problema de o nvtop ser rigoroso demais e acabar travando com frequência
Existem ferramentas dedicadas para cada plataforma, como Metal, CUDA, Pix e PS/Switch
Por isso, muitos pesquisadores ainda tendem a preferir CUDA
O Nsight Systems é uma delas
Queria saber se alguém usa uma GPU 7900 XTX para inferência local ou diffusion
Instalei Linux, mas ela fica ociosa a maior parte do tempo e queria aproveitar melhor
Antes havia problemas relacionados a Python, mas recentemente estabilizou e agora dá até para fazer img2video
Considerando os 24 GB de VRAM, ainda acho que é a placa com o melhor custo-benefício
O ROCm passou recentemente por uma grande reformulação para melhorar a UX, então recomendo conferir o TheRock
O modelo devstral:24b também rodou com boa velocidade
No ComfyUI, quase tudo funcionava bem, mas em tarefas mais incomuns era instável
Ouvi dizer que isso melhorou recentemente