3P by GN⁺ 6일전 | ★ favorite | 댓글 1개
  • GPU 실행을 중단하고 상태를 조사할 수 있는 디버거의 부재에서 출발해, AMD GPU에서 이를 직접 구현하는 과정을 설명
  • DRM 인터페이스와 libdrm을 통해 GPU와 직접 통신하며, 컨텍스트 생성·버퍼 할당·명령 전송 과정을 단계별로 구성
  • TBA/TMA 레지스터와 trap handler를 활용해 GPU 실행을 중단시키고, CPU와의 동기화를 통해 상태를 읽고 복원하는 구조 구축
  • SPIR-V 코드 컴파일과 RADV 통합을 통해 실제 셰이더 디버깅 환경을 확장하고, breakpoint·stepping·watchpoint 기능을 구현 가능하게 함
  • GPU 내부 구조를 직접 제어하는 이 접근은 AMD GPU용 완전한 디버거 구현 가능성을 실증하며, 향후 Vulkan 통합으로 발전 여지 존재

GPU 디버깅의 필요성과 접근

  • CPU처럼 GPU 실행을 일시 중단하고 상태를 점검할 수 있는 도구의 부재에서 출발
    • GPU의 병렬 실행 모델은 디버깅이 훨씬 복잡함
  • AMD ROCm 환경의 rocgdb가 존재하지만 ROCm에 한정된 범위만 지원
  • Marcell Kiss의 블로그 시리즈를 참고해 직접 GPU와 통신하는 디버거 구현을 시도

GPU와 직접 통신하기

  • RADV 드라이버의 동작을 추적하며 GPU와 직접 통신하는 방법을 학습
  • /dev/dri/cardX를 열어 KMD(커널 모드 드라이버) 와 연결 후, amdgpu_device_initialize 호출
  • libdrm을 통해 컨텍스트 생성(amdgpu_cs_ctx_create)버퍼 할당 수행
    • 코드 버퍼와 명령 버퍼 두 개를 생성
  • 버퍼를 GPU/CPU 가상 주소 공간에 매핑
    • amdgpu_bo_va_op 대신 직접 IOCTL 호출로 매핑 처리
  • clangobjdump를 이용해 셰이더 어셈블리 코드 컴파일 및 바이너리 추출
  • PM4 Packet 형식으로 GPU 명령어를 구성해 셰이더 실행 명령 전송

GPU 트랩과 Debugfs 활용

  • RDNA3 ISA의 TBA/TMA 레지스터를 이용해 트랩 핸들러를 설정
    • TBA: 트랩 핸들러 주소
    • TMA: 트랩 핸들러용 임시 메모리 주소
  • 사용자 공간에서 직접 접근 불가하므로 debugfs 인터페이스를 사용
    • /sys/kernel/debug/dri/{PCI address}/regs2 파일을 통해 레지스터 접근
    • amdgpu_debugfs_regs2_write를 이용해 레지스터 쓰기 수행
  • VMID별로 TBA/TMA를 설정해 트랩 핸들러 활성화
    • 각 VMID는 GPU 프로세스 컨텍스트를 구분

트랩 핸들러 구현

  • 트랩 핸들러는 GPU가 예외를 만나면 실행되는 특권 셰이더 프로그램
  • TTMP 레지스터를 이용해 GPU 상태(STATUS, EXEC, VCC 등) 를 저장
  • global_store_addtid_b32 명령으로 스레드별 레지스터 값을 메모리에 저장
  • CPU는 GPU가 데이터를 기록하면 이를 감지하고 SQ_CMD 레지스터로 GPU를 일시 정지
    • 이후 CPU가 데이터를 분석한 뒤 다시 SQ_CMD로 GPU 실행 재개
  • 트랩 핸들러는 복귀 시 프로그램 카운터와 레지스터 상태 복원

SPIR-V 코드 실행과 RADV 통합

  • 수동 어셈블리 대신 SPIR-V 코드 컴파일을 지원
    • RADV의 ACO 컴파일러를 활용해 SPIR-V를 GPU 바이너리로 변환
    • RADV_FORCE_FAMILY 환경 변수로 가상 디바이스 생성
  • RADV의 null_winsys 모드로 실제 하드웨어 접근 없이 컴파일만 수행
  • 컴파일 결과에서 셰이더 코드, 리소스 설정, 디버그 정보를 추출

디버거 기능 확장

  • Stepping: RSRC1.DEBUG_MODE, RSRC3.TRAP_ON_START 비트를 이용해 명령 단위 실행 제어
  • Breakpoints: 코드 버퍼의 주소 기반으로 프로그램 카운터 위치 계산 후 트랩 처리
  • Source Mapping: ACO 컴파일러의 디버그 정보로 소스 코드 라인 매핑
  • Watchpoints: GPU 페이지 보호 또는 SQ_WATCH 레지스터를 이용해 주소 감시 기능 구현 가능
  • 변수 이름·타입 추적: Mesa의 NIR 최적화 단계에서 디버그 정보 전달 개선 필요
  • Vulkan 통합: RADV 기반으로 프레임 단위 디버깅, 버퍼·텍스처·상수 정보 활용 가능

보너스: 사용자 모드 페이지 워킹 코드

  • RDNA3(gfx11) GPU용 페이지 테이블 탐색 코드 예시 제공
    • PDE/PTE 구조체 정의 및 디코딩 함수 포함
    • 가상 주소에서 물리 주소로 변환하는 과정 구현
  • VMID별 페이지 테이블 레지스터를 읽어 GPU 메모리 매핑 구조 분석 가능

결론

  • AMD GPU의 커널·하드웨어 레벨 접근을 통한 완전한 디버거 구현 가능성을 입증
  • CPU와 GPU 간의 양방향 통신 루프를 구축해 실행 중단·상태 분석·재개를 실현
  • 향후 RADV 및 Vulkan 통합을 통해 개발자 친화적인 GPU 디버깅 환경으로 발전 가능성 존재
Hacker News 의견
  • AMD는 아니지만, Metal은 정말 훌륭한 디버거와 개발 도구 세트를 제공함
    그래서 나는 GPU 작업을 할 때 항상 Metal을 먼저 사용하고, 이후 다른 시스템으로 포팅하는 방식을 선호함
    Metal Debugger 문서를 참고하면 좋음
    AAA 게임 개발자는 아니지만, 내 용도에서는 완벽에 가까웠음
    특히 셰이더에서 포맷된 로그 문자열을 출력하면 앱 로그와 함께 섞여 표시되는 기능이 놀라움
    Metal과 OpenGL을 모두 사용하는 GPU 기반 앱을 개발 중인데, OpenGL 쪽에서는 Metal 수준의 툴을 찾기 어려웠음

    • 나는 OpenGL 그래픽 코드를 PS5와 Xbox로 포팅하면서 셰이더를 처음 접했음
      두 플랫폼 모두 전용 디버거를 제공하는데, 그 품질이 꽤 좋았음
      결국 검은 화면만 보일 때는 툴링이 전부임을 깨달았음
      혹시 OpenGL 대신 DirectX를 사용하면 Windows에서 더 나은 툴링을 얻을 수 있는지 궁금함
    • Metal 디버거는 정말 잘 만들어졌지만, 자주 프리징되거나 Xcode가 강제 종료되는 문제가 있음
      특히 compute shader를 다룰 때는 프로파일링이 잘 안 되는 경우가 많음
      그래픽 중심으로 설계된 툴이라, AI나 대용량 버퍼 작업에는 아직 한계가 있는 듯함
    • Xcode의 Metal 디버거는 훌륭하고, Metal API 자체도 직관적임
      OpenGL보다 훨씬 잘 맞았음
      OpenGL 쪽에서는 RenderDoc을 써봤는지? Vulkan/OpenGL용으로는 그게 가장 비슷한 툴임
    • GPU 학습용으로 Mac을 사라는 의견에는 동의하기 어려움
      비싼 컴퓨터를 사서 Metal 전용 API를 디버깅하는 건 비효율적임
      진지하게 그래픽 프로그래밍을 배우려면 Windows나 Linux에서 DX12나 Vulkan을 배우는 게 낫다고 생각함
      RenderDoc 같은 툴을 쓰면 충분히 가능함
      Metal은 좋은 API지만, Apple 플랫폼 밖에서는 쓸 수 없다는 점이 가장 큰 한계임
    • Metal이 멋지긴 하지만, 벤더 종속성(vendor lock-in) 이 문제라고 생각함
      서버나 게임 환경에서는 대부분 AMD나 Nvidia GPU를 사용하므로, Metal 중심 개발은 실용적이지 않음
  • NVIDIA의 CUDA에는 cuda-gdb라는 1st-party GDB가 있음
    공식 문서를 보면 알 수 있듯, CUDA의 스레드 모델과 잘 맞음
    다만 워프 단위로만 단일 스텝 실행이 가능함

  • NVIDIA 카드에서는 NSight를 사용할 수 있고, 다양한 GPU에서 작동하는 RenderDoc도 있음

    • RenderDoc은 고수준 디버거에 가깝고, 성능 분석에도 유용함
      QML이나 QSG_VISUALIZE=overdraw 같은 고수준 시각화가 부족할 때 API 호출 단위로 장면을 추적하는 게 흥미로움
    • nsysnvtx도 훌륭한 도구임
      GPU 없이도 사용할 수 있다는 점을 모르는 사람이 많음
  • AMD용 공식 툴이 있냐는 질문에, GDB가 AMD GPU 디버깅을 지원함
    또한 AMD의 UMR
    Radeon GPU Detective,
    Radeon Developer Tool Suite 같은 도구도 있음

    • 블로그 글을 보면 rocgdb라는 AMD ROCm용 디버거가 언급되어 있음
  • AMD GPU용으로 직접 만든 모니터링 툴을 공유함
    picomon이라는 프로젝트인데, nvtop이 너무 엄격해서 자주 크래시 나는 문제를 해결하려고 만들었음

  • Metal, CUDA, Pix, PS/Switch 등 각 플랫폼마다 전용 툴이 존재함
    이런 이유로 연구자들이 여전히 CUDA를 선호하는 경향이 있음
    Nsight Systems도 그중 하나임

  • 7900 XTX GPU를 로컬 추론(inference) 이나 diffusion에 사용하는 사람 있는지 궁금함
    Linux를 설치했는데 대부분 놀고 있어서 활용하고 싶음

    • Gentoo에서 몇 년째 사용 중임
      예전엔 Python 관련 문제가 있었지만 최근엔 안정화되어 img2video까지 가능함
      24GB VRAM 기준으로는 여전히 가장 가성비 좋은 카드라고 생각함
      ROCm이 최근 UX 개선을 위해 대대적으로 개편되었으니 TheRock을 확인해보길 추천함
    • Windows에서 7900XT로 ollama를 통해 LLM을 로컬 호스팅해봤는데 잘 작동했음
      devstral:24b 모델도 꽤 빠르게 돌았음
    • 출시 초기에 구입했을 때는 ROCm 관련 커널 OOM 오류가 있었음
      ComfyUI에서는 대부분 잘 작동했지만, 특이한 작업에서는 불안정했음
      최근에는 안정화되었다고 들음
    • 6800XT로도 비슷한 작업을 해봤는데, CUDA 중심 생태계라 약간 까다롭지만 가능했음
    • 이미지 및 텍스트 생성 모델을 테스트했는데, 기본 torch 라이브러리를 AMD의 ROCm 버전으로 교체하니 문제없이 작동했음