
나는 지금까지 Unity를 사용한 개발을 하면서 효율적인 성능보다 기능을 구현하기 앞서있었다. 그러다 최근 Unity Performance Tuning Bible이라는 서적을 알게 되었고, 게임 개발을 할 때 성능 튜닝이 얼마나 중요한 지 알게 되었다. 그래서 이 서적을 통해 Unity의 성능 튜닝에 대해 학습해보고자 이 글을 적게 되었다.
서적 원문 : https://github.com/CyberAgentGameEntertainment/UnityPerformanceTuningBible
DeepL 번역본 링크 : https://github.com/CyberAgentGameEntertainment/UnityPerformanceTuningBible/issues/35
1장에서는 성능 튜닝을 진행하기 전에 필요한 사전 준비와 작업 흐름에 대해 설명해준다.
먼저 성능 튜닝을 시작하기 전에 결정해야 할 사항과 고려해야할 사항들을 다룬다. 다음으로 성능 저하가 발생한 애플리케이션에 대해 어떻게 대처해야 하는지에 대해 다룬다. 원인 파악과 해결 방법을 익히면 성능 튜닝의 흐름을 이해할 수 있기때문이다.
성능 튜닝에 앞서 달성하고자 하는 지표를 정해야한다. 세상에는 다양한 사양의 단말기가 넘쳐나고, 저사양 단말기를 사용하는 유저도 있기때문이다. 이런 상황에서 게임 사양, 타깃 유저층, 해외 진출 여부 등 여러 가지를 고려해야한다.
이러한 지표들은 부하를 측정할 만큼의 기능 구현이나 자산이 존재하지 않는 초기 단계에서 결정하기에는 어려움이 많기 때문에 어느 정도 프로젝트가 진행된 후에 결정하는 것이 좋다.
지표를 정하면 목표가 정해지기 때문에 항상 지표를 결정하는 것이 좋다. 아래 표를 통해 결정하면 좋은 지표를 소개한다.
| 항목 | 요소 |
|---|---|
| 프레임 속도 | 항상 어느 정도의 프레임 속도를 목표로 할 것인가? |
| 메모리 | 어느 화면에서 메모리가 최대가 되는지 계산하여 한계치를 결정합니다. |
| 전환 시간 | 트랜지션 시간 대기 시간은 어느 정도가 적절한가? |
| 발열 | 연속 플레이 ?시간 동안 어느 정도의 열을 견딜 수 있는가? |
| 배터리 | 연속 플레이 ?시간 동안 배터리 소모가 허용되는 배터리 소모량 |
위 표에서 특히 프레임 속도와 메모리는 중요한 지표이므로 반드시 결정해야 한다. 이 때는 저사양 단말기보단 볼륨 존에 있는 단말기에 대한 지표를 정해야한다.
여기서 한번 다음과 같은 목표를 설정한 프로젝트가 있다고 가정하고 지표를 정해보자.
이 모호한 목표를 가지고 지표를 정해보자.
이런 식으로 목표로 삼을 지표가 정해지면 검증 단말기를 통해 목표를 맞춰보자. 목표에 도달할 수 없는 수치가 아니라면 지표로 삼을만 하다는 것이다.
이 부분에서는 최대 메모리 사용량에 대해 알아보자. 최대 메모리 사용량을 알기 위해서는 우선 지원 대상 기기가 얼마나 많은 메모리를 확보할 수 있는지를 파악해야 한다. 기본적으로 동작을 보장하는 단말기 중 가장 낮은 사양의 단말기에서 검증하는 것이 좋다.
성능 튜닝을 어디까지 할 것인지를 결정하는 지표로 최소한의 동작을 보장하는 단말기를 결정하는 것도 중요하다. 이 동작 보장 단말의 선정은 경험이 없으면 바로 결정하기 어렵지만, 섣불리 결정하지 말고 우선 저사양 단말의 후보를 찾아내는 것부터 시작하자.
해당 서적의 필자가 추천하는 방법은 'SoC의 스펙'을 측정한 데이터를 참고하는 방법이다. 구체적으로는 벤치마크 측정 앱으로 측정된 데이터를 웹에서 찾아 기준 단말기의 스펙을 파악하고, 그보다 다소 낮은 측정값을 가진 단말기를 몇 가지 패턴으로 선정하는 것이다.
단말기가 선정되면 실제로 애플리케이션을 설치해서 동작하는지 확인한다. 동작이 무거운지 가벼운지 확인하며 점점 조정하는 것이 중요하다.
시장에 다양한 사양의 단말기가 넘쳐나는 지금, 한 가지 사양으로 많은 단말기를 커버하긴 쉽지 않다. 그래서 최근엔 게임 내에서 몇 가지 품질 설정을 설정해 다양한 단말기에서 안정적인 동작을 보장하는 것이 대세다. (옵션)
예를 들면 다음과 같은 항목을 고, 중, 저 품질 설정으로 구분하는 것이 좋다.
단, 외형적인 퀄리티를 떨어뜨리게 되므로 어느 정도까지의 저사양을 허용할 수 있는지 고민해볼 필요가 있다.
성능 저하는 버그와 마찬가지로 시간이 지날수록 다양한 원인이 얽히고설켜 원인을 찾기 힘들어진다. 따라서 가능한 조기에 발견할 수 있는 구조를 애플리케이션에 구현해 놓는 것이 좋다. 구현하기 쉽고 효과적일 수 있는 방법은 화면에 현재 애플리케이션의 상태를 표시하는 것이다. 적어도 현재 프레임 속도와 현재 메모리 사용량은 항상 화면에 표시하는 것을 권장한다.
프레임 속도는 체감상 성능 저하를 알 수 있지만, 메모리는 충돌이 발생해야만 감지할 수 있다. 그래서 항상 화면에 표시해서 메모리 누수를 조기에 발견하는 것이 중요하다.
이 표시 방법을 조금 더 응용해서 프레임 속도 목표가 30일 때 25~30은 녹색, 20~25는 노란색, 그 이하는 빨간색으로 표시하면 직관적으로 알 수 있다.
지금 부턴 성능 튜닝을 어떻게 접근해야 하는지에 대해 설명한다.
성능 튜닝을 할 때 반드시 염두에 두어야 할 두가지가 있다.
- 측정하고 원인을 파악한다. 절때 추측해서는 안 된다.
- 튜닝을 한 후에는 반드시 결과를 비교해야 한다. 전후의 프로파일을 비교하는 것이 좋다. 중요한 것은 수정한 부분뿐만 아니라 전체적으로 성능 저하가 발생하지 않았는지 확인해야 한다는 것이다. 성능 튜닝의 무서운 점은 수정한 부분은 빨라졌지만 다른 부분에서 부하가 증가해 전체적으로는 성능이 저하되는 경우가 드물게 발생하기 때문이다.
이 책에서는 크게 3가지로 구분하여 정의한다.
Cruch : 사용중이던 애플리케이션이 갑자기 정지되거나 비정상적으로 종료되는 현상
-> 메모리 초과와 프로그래밍 실행 오류의 두 가지 원인이 존재하는데 후자는 성능 튜닝의 영역이 아니기 때문에 구체적인 내용은 다루지 않는다.
Screen dropout : 화면이 느려지는 현상
-> CPU나 GPU의 처리 시간이 대부분을 차지한다.
Long loading : 로딩이 오래걸리는 현상
->Screen dropout이랑 동일
이후부턴 메모리와 처리 시간에 초점을 맞춰 성능 저하를 심층적으로 다룬다.
이제부터는 메모리 초과 원인을 좀 더 세분화 한다.
메모리 초과 원인 중 하나로 메모리 누수를 꼽을 수 있습니다. 이를 확인하기 위해 장면 전환에 따라 메모리 사용량이 점차 증가하는지 확인해보자. 여기서 말하는 장면 전환은 단순한 화면 전환이 아니라 크게 화면이 전환되는 것을 말한다. 예를 들어 타이틀 화면에서 아웃게임, 아웃게임에서 인게임 등으로 전환하는 것을 말한다. 측정할 때는 다음과 같은 방법으로 진행한다.
- 한 장면의 메모리 사용량을 메모한다.
- 다른 장면으로 전환한다.
- 1번과 2번을 3~5회 정도 반복한다.
측정 결과, 메모리 사용량이 순증한다면 분명 무언가 누수되고 있는 것이다.
또한 2번을 수행하기 전에 몇 개의 화면 전환을 끼워 넣는 것도 좋다. 왜냐하면 특정 화면에서 로드한 리소스만 예외적으로 누수가 발생했을 가능성도 있기 때문이다.
- 1번과 2번을 반복하는 이유 : 리소스 해제 후 타이밍 문제로 일부 리소스가 해제되지 않는 경우가 있는데 이 해제되지 않는 리소스는 다음 장면으로 넘어가면 해제된다. 이런 부분은 메모리 누수와 구분하기 어렵기 때문에 반복을 통해 구분하는 것이 좋다. 참고로 앞의 경우에는 자원을 해제할 때 어떤 객체가 여전히 참조를 잡고 있다가 해제된 것일 수도 있다. 치명적이지는 않지만, 해결하는 것이 좋다.
메모리 사용량이 많은 경우, 줄일 수 있는 부분을 찾아봐야한다. 1.6 메모리를 줄이자부분에서 구체적인 방법을 설명한다.
먼저 메모리 누수를 재현시킨 후, 다음 소개할 툴을 통해 원인을 찾아보자. 여기서는 간단하게 도구의 특징을 설명한다. 도구 사용법에 대한 자세한 내용은 제 3장 프로파일링 도구에서 구체적으로 설명한다.
Profiler (Memory)
Unith 에디터에 기본적으로 탑재되어 있는 프로파일러 툴이다. 따라서 손쉽게 측정할 수 있다. 기본적으로 Detailed와 Gather object references를 설정한 상태에서 메모리를 스냅샷으로 찍어 조사하게 된다. 이 도구로 측정한 데이터는 다른 도구와 달리 스냅샷 비교는 불가능하다. 자세한 사용법은 3.1.3 Memory에서 확인할 수 있다.
Memory Profiler
이 도구는 Package Manager에서 설치해야 한다. 트리맵에서 메모리 내용을 그래픽으로 표시해준다. 유니티 공식에서 지원한다. 자세한 사용법은 3.4 Memory Profiler에서 확인할 수 있다.
Heap Explorer
이 도구는 Package Manager에서 설치해야 한다. 개인이 개발한 도구지만, 사용하기 쉽고 동작이 가볍다. 참조 관계를 추적할 때 목록 형태로 볼 수 있어 v0.4이전 버전의 Memory Profiler보다 편하다. v0.5버전의 Memory Profiler를 사용할 수 없을 때 대체 도구로 활용하면 좋다. 자세한 사용법은 3.5 Heap Explorer에서 확인할 수 있다.