본문으로 건너뛰기
CHOI HONGSU
1 min read

Gpu profiler

 

https://github.com/hongsulovey/android-gpu-profiler

Gpu profiler

Android GPU Profiler

Android Vulkan / GLES 앱의 GPU 타이밍을 실시간으로 수집하고 분석하기 위한 라이브 스트리밍 GPU 프로파일러입니다.
앱 소스 코드를 수정하지 않고, Android GPU Layer 방식을 이용해 프레임별 GPU 비용과 병목 구간을 확인할 수 있도록 제작했습니다.


프로젝트 개요

Android GPU Profiler는 Android 디바이스에서 실행 중인 Vulkan / GLES 앱의 GPU 타이밍 데이터를 PC로 실시간 전송하고,
프레임 단위의 GPU 비용, RenderPass / Scope별 소요 시간, GPU 부하 추이를 시각적으로 분석하기 위해 만든 개인 R&D 프로젝트입니다.

기존의 RenderDoc이나 Android GPU Inspector가 특정 프레임을 캡처해 깊게 분석하는 도구라면,
이 프로젝트는 실행 중인 앱의 GPU 상태를 시간 흐름에 따라 관찰하는 것에 초점을 둡니다.

특히 모바일 게임 개발 중 다음과 같은 상황을 빠르게 파악하는 것을 목표로 했습니다.

  • 특정 순간에 프레임이 튀는 원인 확인
  • Opaque / Transparent / UI / Blit / Lighting 등 주요 구간의 GPU 비용 추적
  • Unity / Unreal / Native 앱을 소스 수정 없이 연결
  • Vulkan / GLES 레이어 기반으로 실기기 GPU 타이밍 수집
  • 프레임 히스토리와 Scope 타임라인을 통해 병목 구간 시각화

주요 기능

실시간 GPU 타이밍 스트리밍

Android 디바이스에서 수집한 프레임별 GPU 타이밍 데이터를 TCP로 PC Host 앱에 전송합니다.
단일 프레임 캡처가 아니라, 앱이 실행되는 동안 프레임 히스토리를 계속 관찰할 수 있습니다.

Vulkan / GLES Layer 기반 Attach

Android의 GPU Debug Layer 메커니즘을 이용해 대상 앱에 프로파일러 레이어를 주입합니다.
앱 소스 코드를 수정하지 않고, android:debuggable="true" 빌드라면 외부에서 Attach할 수 있도록 설계했습니다.

Host GUI

PC에서 실행되는 Host 앱은 .NET 8 + Avalonia 기반으로 제작했습니다.
프레임 스트립, Scope Gantt 타임라인, GPU Counter 영역, Bottleneck Banner를 통해 병목을 빠르게 확인할 수 있습니다.

병목 분류

수집된 타이밍 정보를 바탕으로 프레임의 주요 병목을 대략적으로 분류합니다.

  • Fragment-bound
  • Vertex-bound
  • UI-bound
  • Overdraw-heavy
  • Blit / Resolve 비용
  • Lighting 비용
  • URP 패턴 추정

Attach 자동화

Host 앱에서 대상 패키지를 선택하면 다음 과정을 자동화합니다.

  • Layer APK 설치
  • Android GPU Debug Layer 설정
  • adb forward 설정
  • 대상 앱 실행
  • Detach 시 설정 정리

왜 만들었는가

모바일 게임 최적화 작업에서는 단일 프레임의 상세 분석도 중요하지만,
실제 플레이 중 “방금 튄 프레임이 왜 느렸는지”를 빠르게 확인하는 것이 더 중요한 경우가 많습니다.

RenderDoc이나 AGI는 특정 프레임을 깊게 보는 데 강하지만,
프레임 흐름 전체를 보면서 병목이 언제, 어떤 패스에서 반복되는지 확인하는 용도로는 아쉬움이 있었습니다.

이 프로젝트는 그런 문제를 해결하기 위해 만들었습니다.

  • 실기기에서 발생하는 GPU 스파이크를 시간 흐름으로 보고 싶다.
  • Unity URP / Unreal / Native 앱을 엔진 수정 없이 연결하고 싶다.
  • 프레임별 Scope 비용을 실시간으로 보고 싶다.
  • 병목 가능성이 높은 구간을 자동으로 요약하고 싶다.
  • 모바일 GPU 특성상 불명확한 Pass 비용을 최대한 실용적으로 해석하고 싶다.

기술 스택

Native Layer

  • C++17
  • Android NDK
  • Vulkan Layer
  • GLES Layer
  • ARM64-v8a
  • TCP Server
  • GPU Timer Query

Host App

  • C#
  • .NET 8
  • Avalonia UI
  • TCP Client
  • 실시간 타임라인 렌더링
  • 프레임 / Scope 데이터 시각화

Android

  • Android 9 이상
  • Vulkan 1.1+
  • GLES 3.0+
  • GL_EXT_disjoint_timer_query
  • ADB / Android Platform Tools

구조