3 pontos por GN⁺ 2025-12-10 | 1 comentários | Compartilhar no WhatsApp
  • 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

 
GN⁺ 2025-12-10
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

    • Tive meu primeiro contato com shaders ao portar código gráfico em OpenGL para PS5 e Xbox
      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
    • O depurador do Metal é realmente muito bem feito, mas costuma congelar com frequência ou fazer o Xcode encerrar à força
      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
    • O depurador de Metal do Xcode é excelente, e a própria API do Metal é intuitiva
      Funcionou muito melhor para mim do que OpenGL
      No lado do OpenGL, você já experimentou o RenderDoc? Para Vulkan/OpenGL, é a ferramenta mais parecida
    • Acho difícil concordar com a ideia de comprar um Mac para aprender GPU
      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
    • Metal é legal, mas acho que a dependência de fornecedor (vendor lock-in) é um problema
      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

    • O RenderDoc é mais um depurador de alto nível e também é útil para análise de desempenho
      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
    • nsys e nvtx também são ferramentas excelentes
      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

    • Em um post de blog, também é mencionado o rocgdb, um depurador para o ROCm da AMD
  • 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

    • Uso há anos no Gentoo
      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
    • No Windows, testei hospedar LLMs localmente com uma 7900XT usando o ollama, e funcionou bem
      O modelo devstral:24b também rodou com boa velocidade
    • Quando comprei no lançamento, havia erros de OOM no kernel relacionados ao ROCm
      No ComfyUI, quase tudo funcionava bem, mas em tarefas mais incomuns era instável
      Ouvi dizer que isso melhorou recentemente
    • Também fiz trabalhos parecidos com uma 6800XT; como o ecossistema é centrado em CUDA, é um pouco mais chato, mas dá para fazer
    • Testei modelos de geração de imagem e texto, e ao trocar a biblioteca padrão do torch pela versão ROCm da AMD, tudo funcionou sem problemas