"게임이 끊겨요" 티켓 진단하기 ① — 프레임 드랍의 원인 4분류

CPU 바운드, GPU 바운드, GC 스파이크, 로딩 히치. 프레임 드랍은 원인 분류가 먼저입니다 — 분류마다 최적화 방향이 정반대이기 때문입니다.

  • unity
  • performance
  • qa

"끊겨요" 티켓 진단 3부작 — ① 원인 4분류 · ② 계측 실전 · ③ 발생 순간 캡처 (③ 공개 예정)

성능 티켓은 버그 티켓 중에서도 재현이 가장 어렵습니다. "인벤토리 열면 끊겨요"라는 티켓을 받은 개발자가 인벤토리를 열어봅니다. 부드럽습니다. 개발자 PC가 QA PC보다 빠르니까요. 결국 티켓은 닫히고, 출시 후 리뷰에 "최적화 좀"이 달립니다.

이 시리즈는 그 티켓을 진단 가능하게 만드는 과정을 다룹니다. 첫 단계는 계측도 최적화도 아니고 분류입니다.

왜 분류가 먼저인가

"끊긴다"는 하나의 증상이지만 원인은 대체로 넷 중 하나이고, 넷의 처방은 서로 정반대입니다. GPU 바운드 게임에서 스크립트를 최적화하면 아무것도 좋아지지 않습니다. GC 스파이크 게임에서 그래픽 품질을 낮춰도 히치는 그대로입니다. 분류를 건너뛴 최적화는 방향 없는 삽질이 됩니다.

1. CPU 바운드 — 메인 스레드가 못 따라간다

스크립트(Update), 물리, 애니메이션, UI 레이아웃이 프레임 예산(60fps 기준 16.6ms)을 넘는 경우입니다.

시그니처: 프레임 타임이 전반적으로 높고, 특정 상황(적이 많을 때, UI가 복잡할 때)에서 비례해서 나빠집니다. 해상도를 낮춰도 변화가 없습니다 — 이게 GPU 바운드와 가르는 가장 빠른 판별법입니다.

2. GPU 바운드 — 그리는 쪽이 못 따라간다

드로우콜 과다, 오버드로우, 무거운 셰이더, 고해상도가 원인입니다.

시그니처: 해상도나 품질 설정을 낮추면 즉시 좋아집니다. CPU 프레임 타임은 여유가 있는데 화면은 끊깁니다 — CPU가 GPU를 기다리는 시간(Gfx.WaitForPresent 계열)이 길게 잡힙니다.

저희가 실제로 겪은 사례가 이 유형이었습니다. Windows에서만 보고된 스터터링을 저희 SDK의 캡처 부하로 의심했는데, 계측해 보니 SDK를 꺼도 동일했고 원인은 게임 자체가 GPU 바운드인 것이었습니다. 체감과 추측은 범인을 자주 틀립니다. 이 판정 과정은 2편에서 다룹니다.

3. GC 스파이크 — 주기적으로 한 번씩 크게 멈춘다

매 프레임은 멀쩡한데 몇 초에 한 번씩 수십 ms짜리 히치가 옵니다. 매 프레임 할당되는 관리 힙 메모리(문자열 연결, 클로저, LINQ, new 되는 컬렉션)가 쌓여 GC가 도는 순간입니다.

시그니처: 프레임 타임 그래프가 평평하다가 주기적인 바늘 모양 스파이크를 찍습니다. 스파이크 간격은 할당 속도에 반비례합니다 — 전투처럼 할당이 많은 상황에서 간격이 짧아지면 거의 확정입니다.

4. 로딩 히치 — 특정 순간에만 한 번 멈춘다

씬 전환, 에셋 로드, 오브젝트 최초 등장, 셰이더 첫 컴파일처럼 이벤트에 결합된 단발성 멈춤입니다.

시그니처: 주기성이 없고 재현 조건이 명확합니다. "이 보스가 처음 나올 때만", "이 맵 처음 진입할 때만". 두 번째부터는 안 끊긴다면(캐시·컴파일 완료) 거의 이 유형입니다. 셰이더 컴파일 히치는 빌드에서만 나고 에디터에서는 재현되지 않는 경우가 많아 "재현 불가"로 닫히기 특히 쉽습니다.

티켓에서 분류 힌트 읽기

티켓 표현유력한 분류
"전투만 들어가면 전반적으로 무거워요"CPU 바운드
"옵션 낮추니까 괜찮아졌어요"GPU 바운드
"몇 초에 한 번씩 컥컥 걸려요"GC 스파이크
"이 맵 처음 들어갈 때만 멈춰요"로딩 히치

물론 이 표는 정황 증거입니다. 확정하려면 계측이 필요하고, QA의 체감 표현을 계측 데이터로 바꾸는 방법이 다음 편의 주제입니다.


성능 티켓이 "재현 불가"로 닫히는 구조는 일반 버그와 같습니다 — 발생 순간의 증거가 남지 않았기 때문입니다. 무엇을 남겨야 하는지는 버그 리포트 3부작에서 다뤘습니다.