TECHARTNOMAD | TECHARTFLOWIO.COM

UNITY3D

고객사와 함께 읽는 울티밋 가이드 프로파일링 유니티

jplee 2025. 7. 8. 00:41

유니티 테크놀로지에서 발행 한 울티밋 가이드 시리즈 프로파일링 유니티 영문판을 번역 한 것입니다.
고객사 분과 함께 보며 직접 프로파일러를 보고 살펴볼  수 있는 기회를 만들고 있습니다.


원활한 성능은 플레이어에게 몰입감 있는 게임 경험을 제공하는 데 필수적입니다. 다양한 플랫폼과 기기에 맞게 게임 성능을 프로파일링하고 최적화함으로써 플레이어 기반을 확장하고 성공 가능성을 높일 수 있습니다.
이 가이드는 Unity에서 애플리케이션을 프로파일링하고, 메모리를 관리하며, 전력 소비를 최적화하는 방법에 관한 고급 조언과 지식을 처음부터 끝까지 제공합니다.
효율적인 게임 개발에 "필수"인 일관된 엔드투엔드 프로파일링 워크플로우는 다음과 같은 세 가지 간단한 절차로 시작됩니다:

  • 주요 변경 전 프로파일링: 기준선 설정
  • 개발 중 프로파일링: 변경 사항이 성능이나 예산을 초과하지 않도록 추적 및 확인
  • 변경 후 프로파일링: 변경 사항이 원하는 효과를 가져왔는지 확인

효율적인 코드와 최적화된 메모리 사용은 저사양 및 고사양 기기 모두에서 더 나은 성능을 제공합니다. 발열 제어에 주의를 기울이면 모바일 기기의 소중한 배터리 주기를 절약할 수 있습니다. 전반적으로, 좋은 성능은 플레이어의 편안함을 높여 더 많은 사용자 확보와 유지를 가능하게 합니다.
이 가이드의 주요 저자는 소프트웨어 엔지니어이자 게임 개발자인 션 더피입니다. 션은 6년 이상 전문 Unity 개발자를 위한 과정, 교육 및 도구를 개발해 왔으며, Unity Games by Tutorials을 포함한 Unity 게임 개발 서적을 공동 집필했습니다.
스티븐 캐너반, 스티브 맥그릴, 마틴 틸로 슈미츠를 포함한 시니어 Unity 엔지니어들도 이 전자책 제작에 기여했습니다.
Unity에서 제공하는 성능 최적화에 관한 추가 가이드로는 콘솔 및 PC용 게임 성능 최적화모바일용 게임 성능 최적화가 있습니다.
Unity 팀은 여러분의 프로파일링 및 최적화 노력에 행운을 빕니다.
 
유니티에서 게임을 프로파일링하는 방법에 대한 세부 사항을 살펴보기 전에, 주요 개념과 프로파일링 원칙을 간략히 요약해 보겠습니다.
프로파일러는 코드의 메모리 및 성능 병목 현상을 식별하는 데 가장 유용한 개발자 도구 중 하나입니다.
프로파일러는 애플리케이션 성능이 지연되는 이유나 코드가 과도한 메모리를 할당하는 이유에 대한 의문을 해결하는 데 도움을 주는 탐정 도구라고 생각하세요. 이를 통해 유니티 엔진의 내부 작동 방식을 이해할 수 있습니다.
유니티는 코드를 분석하고 최적화하기 위한 다양한 프로파일링 도구를 제공합니다.
에디터 내에서뿐만 아니라 하드웨어에서도 사용 가능합니다. 또한 Arm, Apple, PlayStation, Xbox 등에서 제공하는 각 대상 플랫폼의 네이티브 프로파일링 도구를 사용하는 것이 좋습니다.

유니티에서 프로파일링 이해하기

유니티의 프로파일링 도구는 에디터 및 패키지 매니저를 통해 사용할 수 있습니다.

  • 유니티 프로파일러: 유니티 에디터, 플레이 모드의 애플리케이션 성능을 측정하거나 개발 모드에서 실행 중인 애플리케이션이 설치된 기기에 연결할 수 있습니다
  • 프로파일링 코어 패키지: 유니티 프로파일러 캡처에 컨텍스트 정보를 추가하는 데 사용할 수 있는 API 제공
  • 메모리 프로파일러: 심층적인 메모리 성능 분석을 제공하는 도구
  • 프로파일 분석기: 두 개의 프로파일링 데이터셋을 비교하여 변경 사항이 애플리케이션 성능에 미치는 영향을 분석

"유니티 프로파일링 및 디버그 도구" 섹션에서는 프레임 디버거와 함께 이러한 도구 사용에 대한 자세한 정보를 제공합니다.

샘플 기반 vs 계측 프로파일링

게임 성능을 프로파일링하는 두 가지 일반적인 방법이 있습니다:

  • 샘플 기반 프로파일링
  • 계측 프로파일링

샘플 기반 프로파일링은 애플리케이션에서 수행 중인 작업에 대한 통계 데이터를 수집한 다음 분석하는 방식입니다.
샘플 기반 프로파일러는 매 "n" 나노초마다 콜 스택을 탐색하고 콜 스택 정보를 사용하여 함수가 언제 호출되었는지(그리고 어떤 함수에 의해), 또한 얼마나 오래 실행되었는지 파악합니다.
이 프로파일링 방법의 정확도는 더 높은 샘플링 빈도를 사용함으로써 향상됩니다. 이는 짧은 함수 호출이 콜 스택에서 누락되지 않기 때문입니다.
그러나 이는 더 높은 오버헤드로 이어집니다.

계측 기반 프로파일러

계측 기반 프로파일링은 프로파일러 마커를 추가하여 코드를 "계측"하는 방식으로, 각 마커 내 코드가 실행되는 데 걸리는 시간에 대한 자세한 타이밍 정보를 기록합니다. 이 프로파일러는 각 마커에 대한 시작과 종료 이벤트의 스트림을 캡처합니다.
이 방법은 정보를 손실하지 않지만, 프로파일링 데이터를 캡처하기 위해 마커가 배치되어야 합니다.
유니티 프로파일러는 계측 기반입니다. 대부분의 유니티 API 표면에 마커를 설정함으로써 세부 정보와 오버헤드 간의 균형을 잘 유지합니다.
중요한 네이티브 기능과 스크립팅 코드 베이스 메시지 호출은
너무 많은 오버헤드 없이 가장 중요한 "큰 그림"을 캡처하도록 계측됩니다.
이를 통해 코드 성능을 탐색하고, 성능 문제를 쉽게 찾고, 빠른 최적화 개선점을 발견할 수 있으며, 사용자 정의 프로파일러 마커를 추가하거나 딥 프로파일링을 사용하여 더 깊이 들어갈 수 있는 옵션도 있습니다.
딥 프로파일링은 C# Getter 및 Setter 속성을 포함한 모든 스크립팅 메서드 호출에 자동으로 시작 및 종료 마커를 삽입합니다. 이 시스템은 스크립팅 측면에서 전체 프로파일링 세부 정보를 제공하지만, 캡처된 프로파일링 범위 내에 있는 호출 수에 따라 보고된 타이밍 데이터가 부풀려질 수 있는 오버헤드가 동반됩니다.

유니티에서의 계측 기반 프로파일링

위에서 언급한 스크립팅 코드 베이스 메시지 호출(기본적으로 명시적으로 계측됨)은 일반적으로 유니티 네이티브 코드에서 관리 코드로의 호출 스택 깊이의 첫 번째 수준을 포함합니다.
예를 들어, Start(), Update(), FixedUpdate() 등과 같은 일반적인 MonoBehaviour 메서드가 포함됩니다.

예제 스크립트를 프로파일링하면 Unity Instantiate() 메서드에 대한 Update() 메서드 호출이 표시됩니다
프로파일러에서 Unity API로 다시 호출하는 관리형 스크립팅 코드의 하위 샘플도 볼 수 있습니다. 그러나 한 가지 주의할 점은 해당 Unity API 코드 자체에 계측 프로파일러 마커가 필요하다는 것입니다. 대부분의 Unity
API는 성능 오버헤드가 있는 경우 계측됩니다. 예를 들어, Camera.main을 사용하면 프로파일 캡처에 FindMainCamera 마커가 나타납니다. 캡처된 프로파일링 데이터셋을 검사할 때는
다양한 마커의 의미를 아는 것이 유용합니다. 일반적인 프로파일러 마커 목록을 사용하여 자세히 알아보세요.

Camera.main을 사용하면 프로파일 캡처에 FindMainCamera 마커가 나타납니다.

프로파일러 마커로 프로파일링 세부 정보 증가

기본적으로 Unity 프로파일러는 프로파일러 마커로 명시적으로 래핑된 코드 타이밍을 프로파일링합니다. 코드의 주요 함수에 프로파일러 마커를 수동으로 삽입하는 것은 전체 딥 프로파일링 오버헤드 없이 프로파일링 실행의 세부 수준을 늘리는 효율적인 방법이 될 수 있습니다.

프로파일러 모듈

프로파일러는 병목 현상을 식별하는 데 도움이 되는 프레임별 성능 지표를 캡처합니다.
CPU 사용량, GPU, 렌더링, 메모리, 물리 등과 같은 프로파일러에 포함된 프로파일러 모듈을 사용하여 세부 정보를 자세히 살펴볼 수 있습니다.

메인 프로파일러
창 보기, 왼쪽에 모듈과 하단에 세부 정보 패널이 표시됨
프로파일러 창은 현재 선택된 프로파일러 모듈로 캡처된 세부 정보를 보기 하단의 패널에 나열합니다. 예를 들어, CPU 사용량 프로파일러 모듈은 CPU 작업의 타임라인 또는 계층 구조 보기를 특정 시간과 함께 표시합니다.

CPU 사용량 모듈 타임라인 보기, 메인 및 렌더 스레드 마커 세부 정보 표시
Unity 프로파일러를 사용하여 애플리케이션의 성능을 평가하고 특정 영역과 문제를 자세히 살펴보세요. 기본적으로 프로파일러는 Unity 에디터 플레이어 인스턴스에 연결됩니다.
에디터에서 프로파일링과 독립 실행형 빌드 프로파일링 사이에는 성능 차이가 크다는 점을 알아두세요. 프로파일러를 대상 하드웨어에서 직접 실행되는 독립 실행형 빌드에 연결하는 것이 항상 바람직한데, 이는 에디터 오버헤드 없이 가장 정확한 결과를 얻을 수 있기 때문입니다.
P RO F I L ING WORK F LOW
이 섹션에서는 프로파일링 시 유용한 몇 가지 목표를 식별합니다. 또한 CPU 바운드 또는 GPU 바운드와 같은 일반적인 성능 병목 현상을 살펴보고, 이러한 상황을 식별하고 더 자세히 조사하는 방법에 대한 세부 정보를 제공합니다.
마지막으로 메모리 프로파일링에 대해 알아봅니다. 이는 런타임 성능과 크게 관련이 없지만 게임 충돌을 방지할 수 있기 때문에 알아두는 것이 중요합니다.

프레임 예산 설정

게임의 프레임 속도를 초당 프레임(fps)으로 측정하는 것은 플레이어에게 일관된 경험을 제공하는 데 이상적이지 않습니다. 다음 단순화된 시나리오를 고려해 보세요:
단순화된 시나리오:
런타임 중에 게임이 0.75초 동안 59개의 프레임을 렌더링합니다. 그러나 다음 프레임은 렌더링하는 데 0.25초가 걸립니다. 평균 제공 프레임 속도가 60fps로 좋아 보이지만, 실제로는 마지막 프레임이 렌더링되는 데 1/4초가 걸리기 때문에 플레이어는 버벅거림 효과를 느낄 것입니다.
이것이 프레임당 특정 시간 예산을 목표로 하는 것이 중요한 이유 중 하나입니다. 이는 프로파일링과 게임 최적화 시 달성해야 할 확실한 목표를 제공하며, 궁극적으로 플레이어에게 더 부드럽고 일관된 경험을 만들 수 있도록 도와줍니다.
게임을 프로파일링하고 최적화할 때 달성해야 할 확실한 목표를 제공하며, 궁극적으로 플레이어에게 더 부드럽고 일관된 경험을 만들 수 있도록 도와줍니다.
각 프레임은 목표 fps를 기반으로 한 시간 예산을 갖게 됩니다. 30fps를 목표로 하는 애플리케이션은 항상 프레임당 33.33ms 미만(1000ms / 30fps)이어야 합니다. 마찬가지로 60fps 목표는 프레임당 16.66ms를 남깁니다.
UI 메뉴 표시나 장면 로딩과 같은 비대화형 시퀀스 동안에는 이 예산을 초과할 수 있지만, 게임 플레이 중에는 그렇지 않습니다. 목표 프레임 예산을 초과하는 단 하나의 프레임조차도 버벅거림을 일으킬 수 있습니다.

VR 게임에서 일관되게 높은 프레임 속도는 플레이어에게 메스꺼움이나 불편함을 주는 것을 방지하는 데 필수적입니다. 그렇지 않으면 게임 인증 과정에서 플랫폼 소유자에 의해 거부될 위험이 있습니다.
초당 프레임: 잘못된 지표

게이머가 성능을 측정하는 일반적인 방법은 프레임 속도 또는 초당 프레임입니다. 그러나 대신 밀리초 단위의 프레임 시간을 사용하는 것이 좋습니다. 그 이유를 이해하려면 fps와 프레임 시간의 그래프를 살펴보세요.
fps vs . frame time

다음 숫자들을 고려해보세요:
1000 ms/초 / 900 fps = 1.111 ms/프레임
1000 ms/초 / 450 fps = 2.222 ms/프레임
1000 ms/초 / 60 fps = 16.666 ms/프레임
1000 ms/초 / 56.25 fps = 17.777 ms/프레임
애플리케이션이 900 fps로 실행되는 경우, 이는 프레임당 1.111 밀리초의 프레임 시간으로 변환됩니다. 450 fps에서는 프레임당 2.222 밀리초입니다. 이는
프레임 속도가 절반으로 떨어진 것처럼 보이지만, 실제로는 프레임당 단지 1.111 밀리초의 차이만 있습니다.
60 fps와 56.25 fps의 차이를 살펴보면, 각각 프레임당 16.666 밀리초와 17.777 밀리초로 변환됩니다.
이 또한 프레임당 1.111 밀리초의 추가 시간을 나타내지만, 여기서 프레임 속도의 감소는 백분율 측면에서 훨씬 덜 극적으로 느껴집니다.
이것이 개발자들이 fps 대신 평균 프레임 시간을 사용하여 게임 속도를 벤치마킹하는 이유입니다.
목표 프레임 속도 아래로 떨어지지 않는 한 fps에 대해 걱정하지 마세요. 게임이 얼마나 빠르게 실행되는지 측정하려면 프레임 시간에 집중한 다음, 프레임 예산 내에 머무르세요.
더 자세한 정보는 "로버트 던롭의 fps 대 프레임 시간" 원문을 참조하세요.

모바일 과제: 열 제어 및 배터리 수명

열 제어는 모바일 기기용 애플리케이션을 개발할 때 최적화해야 할 가장 중요한 영역 중 하나입니다. 비효율적인 코드로 인해 CPU나 GPU가 최대 성능으로 너무 오래 작동하면 칩이 뜨거워집니다. 칩 손상(그리고 잠재적으로 플레이어의 손을 화상시키는 것)을 방지하기 위해 운영 체제는 기기가 냉각될 수 있도록 클럭 속도를 줄입니다.
이로 인해 프레임 끊김 현상과 좋지 않은 사용자 경험이 발생합니다. 이러한 성능 저하를 열 스로틀링이라고 합니다.
높은 프레임 속도와 증가된 코드 실행(또는 DRAM 접근 작업)은 배터리 소모와 열 발생을 증가시킵니다. 나쁜 성능은 또한 저사양 모바일 기기의 전체 세그먼트를 제외시킬 수 있어 시장 기회를 놓칠 수 있습니다.
열 문제를 다룰 때는 작업 예산을 시스템 전체 예산으로 고려하세요.
초기 프로파일링 기술을 활용하여 게임을 처음부터 최적화함으로써 열 스로틀링과 배터리 소모를 방지하세요. 열과 배터리 소모 문제를 해결하기 위해 대상 플랫폼 하드웨어에 맞게 프로젝트 설정을 조정하세요.

모바일에서 프레임 예산 조정

프레임 유휴 시간을 약 35% 정도 남겨두는 것이 장시간 플레이 시 기기 열 문제를 해결하기 위한 일반적인 권장 사항입니다.
이렇게 하면 모바일 칩이 냉각될 시간을 확보하고 과도한 배터리 소모를 방지할 수 있습니다. 프레임당 33.33ms의 목표 프레임 시간(30fps 기준)을 사용할 경우, 모바일 기기의 일반적인 프레임 예산은 프레임당 약 22ms가 됩니다.
계산은 다음과 같습니다: (1000ms / 30) * 0.65 = 21.66ms
동일한 계산을 사용하여 모바일에서 60fps를 달성하려면 (1000ms / 60) * 0.65 = 10.83ms의 목표 프레임 시간이 필요합니다. 이는 많은 모바일 기기에서 달성하기 어렵고 30fps를 목표로 할 때보다 배터리를 두 배 더 빨리 소모합니다. 이러한 이유로 대부분의 모바일 게임은 60fps가 아닌 30fps를 목표로 합니다. 이 설정을 제어하려면 Application.targetFrameRate를 사용하고, 프레임 시간에 대한 자세한 내용은 프레임 예산 설정 섹션을 참조하세요.
모바일 칩의 주파수 스케일링은 프로파일링 시 프레임 유휴 시간 예산 할당을 식별하기 어렵게 만들 수 있습니다. 개선 및 최적화가 긍정적인 효과를 가져올 수 있지만, 모바일 기기가 주파수를 낮추어 결과적으로 더 냉각될 수 있습니다. 최적화 전후의 모바일 칩 주파수, 유휴 시간 및 스케일링을 모니터링하려면 FTrace 또는 Perfetto와 같은 맞춤형 도구를 사용하세요.
목표 fps(30fps의 경우 33.33ms)에 대한 총 프레임 시간 예산 내에 머물고 이 프레임 속도를 유지하기 위해 기기가 더 적게 작동하거나 더 낮은 온도를 기록하는 것을 확인하면 올바른 방향으로 가고 있는 것입니다.

프레임 예산 허용 최적화 결과를 파악하는 데 도움이 되는 FTrace 또는 Perfetto와 같은 툴로 CPU 주파수 및 유휴 상태를 모니터링합니다.

모바일 기기에서 프레임 예산에 여유를 두는 또 다른 이유는 실제 환경에서의 온도 변화를 고려하기 위함입니다. 더운 날에는 모바일 기기가 뜨거워지고 열 발산에 어려움을 겪을 수 있으며, 이로 인해 열 스로틀링과 게임 성능 저하가 발생할 수 있습니다. 프레임 예산의 일부를 여유로 두면 이러한 상황을 피하는 데 도움이 됩니다.

메모리 접근 작업 줄이기

DRAM 접근은 일반적으로 모바일 기기에서 전력을 많이 소모하는 작업입니다. Arm의 모바일 기기에서의 그래픽 콘텐츠 최적화 권장 사항에 따르면 LPDDR4 메모리 접근은 바이트당 약 100 피코줄의 비용이 듭니다.
프레임당 메모리 접근 작업 수를 줄이는 방법:

  • 프레임 속도 줄이기
  • 가능한 경우 디스플레이 해상도 줄이기
  • 정점 수와 속성 정밀도가 감소된 단순한 메시 사용하기
  • 텍스처 압축 및 밉맵핑 사용하기

Arm 또는 Arm Mali 하드웨어를 활용하는 기기에 초점을 맞춰야 할 때, Arm Mobile Studio 도구(특히 Streamline Performance Analyzer)는 메모리 대역폭 문제를 식별하기 위한 우수한 성능 카운터를 제공합니다. 이 카운터는 각 Arm GPU 세대별로 나열되고 설명되어 있습니다. 예를 들어, Mali-G78입니다. Mobile Studio GPU 프로파일링에는 Arm Mali가 필요하다는 점에 유의하세요.

Arm의 Streamline Performance Analyzer는 타겟 Arm 하드웨어에서 실시간 프로파일링 세션 중에 캡처할 수 있는 다양한 성능 카운터 정보를 제공합니다. 이는 오버드로우로 인한 메모리 대역폭 포화와 같은 성능 문제를 식별하는 데 탁월합니다.

벤치마킹을 위한 하드웨어 등급 설정
플랫폼별 프로파일링 도구를 사용하는 것 외에도, 지원하고자 하는 각 플랫폼과 품질 등급에 대한 최저 사양 기기를 설정한 다음, 각 사양에 대한 성능을 프로파일링하고 최적화하세요.
예를 들어, 모바일 플랫폼을 대상으로 한다면 대상 하드웨어에 따라 기능을 켜거나 끄는 품질 제어가 있는 세 가지 등급을 지원하기로 결정할 수 있습니다. 그런 다음 각 등급에서 가장 낮은 기기 사양에 맞게 최적화합니다. 또 다른 예로, PlayStation 4와 PlayStation 5 모두를 위한 게임을 개발하는 경우 두 플랫폼 모두에서 프로파일링해야 합니다.

모바일 최적화에 대한 전체 가이드는 모바일 게임 성능 최적화하기를 참조하세요. 이 가이드는 게임을 실행하는 모바일 기기의 열 스로틀링을 줄이고 배터리 수명을 늘리는 데 도움이 되는 많은 팁과 트릭을 제공합니다.

상위 수준에서 하위 수준 프로파일링까지

프로파일링 시 상위에서 하위로 접근하는 방식이 효과적이며, 딥 프로파일링을 비활성화한 상태로 시작하세요. 이 상위 수준 접근 방식을 사용하여 데이터를 수집하고 핵심 게임 루프 영역에서 원치 않는 관리 할당이나 너무 많은 CPU 시간을 소비하는 시나리오에 대한 메모를 작성하세요.
먼저 GC.Alloc 마커에 대한 콜 스택을 수집해야 합니다. 이 과정에 익숙하지 않다면, 이 가이드의 뒷부분에 있는 애플리케이션 수명 동안 반복되는 메모리 할당 찾기 섹션에서 팁과 요령을 확인하세요.
보고된 콜 스택이 할당 출처나 기타 속도 저하의 원인을 추적하기에 충분히 상세하지 않은 경우, 딥 프로파일링을 활성화한 두 번째 프로파일링 세션을 수행하여 할당 출처를 찾을 수 있습니다.
프레임 시간 '위반자'에 대한 메모를 수집할 때, 프레임의 나머지 부분과 비교하여 어떤 영향을 미치는지 기록해 두세요. 이 상대적 영향은 딥 프로파일링을 켜면 달라집니다.
이 가이드의 뒷부분에서 딥 프로파일링에 대해 더 자세히 알아보세요.

초기 프로파일링

프로파일링을 통한 최상의 성과는 프로젝트 개발 주기 초기에 시작할 때 얻을 수 있습니다.
자주 프로파일링하여 팀이 프로젝트의 "성능 서명"을 이해하고 기억하도록 하세요. 성능이 급격히 저하되면 문제가 발생한 시점을 쉽게 발견하고 해결할 수 있습니다.
가장 정확한 프로파일링 결과는 항상 대상 기기에서 빌드를 실행하고 프로파일링하면서
각 플랫폼의 하드웨어 특성을 파악하기 위해 플랫폼별 도구를 활용하는 것에서 나옵니다. 이러한 조합은 모든 대상 기기에서 애플리케이션 성능에 대한 전체적인 뷰를 제공합니다.

병목 현상 찾기

일부 플랫폼에서는 애플리케이션이 CPU 또는 GPU 바운드인지 쉽게 확인할 수 있습니다. 예를 들어, Xcode에서 iOS 게임을 실행할 때 fps
패널에는 총 CPU 및 GPU 시간이 막대 차트로 표시되어 어느 것이 더 높은지 확인할 수 있습니다. CPU 시간에는 VSync 대기 시간이 포함된다는 점에 유의하세요,
모바일 기기에서는 항상 VSync가 활성화되어 있습니다.


VSync란 무엇인가요?

VSync는 애플리케이션의 프레임 속도를 모니터의 주사율과 동기화합니다.

즉, 60Hz 모니터를 사용하고 게임이 16.66ms의 프레임 예산 내에서 실행된다면, 더 빠르게 실행되는 것이 아니라 강제로 60fps로 실행됩니다. 모니터의 주사율과 fps를 동기화하면

GPU 부담이 줄어들고 화면 찢어짐과 같은 시각적 아티팩트를 방지할 수 있습니다. Unity에서는

품질 설정(Edit > Project Settings > Quality)에서 VSync Count 속성을 구성할 수 있습니다.

하지만 일부 플랫폼에서는 GPU 타이밍 데이터를 얻기가 어려울 수 있습니다. 다행히도, Unity 프로파일러는 성능 병목 현상의 위치를 식별하기에 충분한 정보를 보여줍니다. 아래 흐름도는 초기 프로파일링 과정을 보여주며, 이어지는 섹션에서는 각 단계에 대한 자세한 정보를 제공합니다. 또한 실제 Unity 프로젝트의 프로파일러 캡처를 통해 살펴봐야 할 사항들을 보여줍니다.
CPU가 GPU를 기다리는 시간을 포함한 모든 CPU 활동의 종합적인 그림을 얻으려면 프로파일러의 CPU 사용 모듈에서 타임라인 뷰를 사용하세요. 캡처를 올바르게 해석하기 위해 일반적인 프로파일러 마커에 익숙해지세요.
일부 프로파일러 마커는 대상 플랫폼에 따라 다르게 나타날 수 있으므로, 각 대상 플랫폼에서 게임 캡처를 탐색하여 프로젝트의 "정상적인" 캡처가 어떤 모습인지 파악하는 데 시간을 투자하세요.
프로젝트의 성능은 가장 오래 걸리는 칩 및/또는 스레드에 의해 제한됩니다. 그것이 최적화 노력을 집중해야 할 영역입니다. 예를 들어, 목표 프레임 시간 예산이 33.33ms이고 VSync가 활성화된 게임을 상상해보세요:

  • CPU 프레임 시간(VSync 제외)이 25ms이고 GPU 시간이 20

ms라면, 문제 없습니다! CPU에 바운드되어 있지만 모든 것이 예산 내에 있으며, 최적화를 해도 프레임 속도가 향상되지 않습니다(CPU와 GPU 모두 16.66ms 이하로 내려가 60fps로 점프하지 않는 한).

  • CPU 프레임 시간이 40ms이고 GPU가 20ms라면, CPU에 바운드되어 있으므로 CPU 성능을 최적화해야 합니다. GPU

성능을 최적화해도 도움이 되지 않습니다. 오히려 균형을 맞추기 위해 일부 CPU 작업을 GPU로 이동시키는 것이 좋을 수 있습니다. 예를 들어, 일부 작업에 C# 코드 대신 컴퓨트 셰이더를 사용하는 것입니다.

  • CPU 프레임 시간이 20ms이고 GPU가 40ms라면, GPU에 바운드되어 있으므로 GPU 작업을 최적화해야 합니다.
  • CPU와 GPU가 모두 40ms라면, 둘 다에 바운드되어 있으므로 30fps에 도달하기 위해 둘 다 33.33ms 이하로 최적화해야 합니다.

CPU 또는 GPU 바운드에 대해 더 자세히 알아볼 수 있는 리소스:

프레임 예산 내에 있나요?

개발 과정 전반에 걸쳐 프로젝트를 일찍, 자주 프로파일링하고 최적화하면 애플리케이션의 모든 CPU 스레드와 전체 GPU 프레임 시간이 프레임 예산 내에 있도록 보장하는 데 도움이 됩니다.
아래는 지속적인 프로파일링과 최적화를 수행한 팀이 개발한 Unity 모바일 게임의 프로파일링 캡처 이미지입니다. 이 게임은 고사양 모바일 폰에서는 60fps를, 이 캡처와 같은 중/저사양 폰에서는 30fps를 목표로 합니다.

30fps에 필요한 약 22ms의 프레임 예산 내에서 과열 없이 안정적으로 실행되는 게임입니다. 메인 스레드 시간을 VSync까지 채우 WaitForTargetfps 패딩과 렌더 스레드 및 워커 스레드의 회색 유휴 시간에 주목하세요. 또한 VBlank 간격은 프레임별 Gfx.Present의 종료 시간을 확인하여 관찰할 수 있으며, 타임라인 영역이나 상단의 시간 눈금자에서 시간 스케일을 그려 이들 사이를 측정할 수 있습니다.
선택한 프레임에서 시간의 거의 절반이 노란색 WaitForTargetfps 프로파일러 마커로 채워져 있음에 주목하세요. 애플리케이션이 Application.
targetFrameRate를 30fps로 설정했고 VSync가 활성화되어 있습니다. 메인 스레드의 실제 처리 작업은 약 19ms 지점에서 완료되고, 나머지 시간은 다음 프레임을 시작하기 전에 33.33ms의 나머지 시간이 경과할 때까지 대기하는 데 사용됩니다.
이 시간이 프로파일러 마커로 표시되지만, 메인 CPU 스레드는 이 시간 동안 본질적으로 유휴 상태이므로 CPU가 냉각되고 배터리 전력을 최소한으로 사용할 수 있습니다.
확인해야 할 마커는 다른 플랫폼이나 VSync가 비활성화된 경우 다를 수 있습니다. 중요한 것은 메인 스레드가 프레임 예산 내에서 실행되고 있는지, 또는 애플리케이션이 VSync를 기다리고 있음을 나타내는 어떤 종류의 마커와 함께 정확히 프레임 예산에 맞게 실행되고 있는지, 그리고 다른 스레드에 유휴 시간이 있는지 확인하는 것입니다.
유휴 시간은 회색 또는 노란색 프로파일러 마커로 표시됩니다. 위의 스크린샷은 렌더 스레드가 Gfx.WaitForGfxCommandsFromMainThread에서 유휴 상태임을 보여줍니다.
이는 한 프레임에서 GPU로 드로우 콜 전송을 완료하고 다음 프레임에서 CPU로부터 더 많은 드로우 콜 요청을 기다리는 시간을 나타냅니다.
마찬가지로, Job Worker 0 스레드가 Canvas.GeometryJob에서 일부 시간을 보내지만 대부분의 시간은 유휴 상태입니다. 이는 모두 프레임 예산 내에서 편안하게 실행되고 있는 애플리케이션의 징후입니다.

게임이 프레임 예산 내에 있는 경우

배터리 사용량과 열 제한을 고려하기 위한 예산 조정을 포함하여 프레임 예산 내에 있다면, 다음 번까지 성능 프로파일링을 완료한 것입니다 - 축하합니다.
메모리 프로파일러를 실행하여 애플리케이션이 메모리 예산 내에 있는지도 확인하는 것이 좋습니다.

CPU 바운드

게임이 CPU 프레임 예산 내에 있지 않다면, 다음 단계는 CPU의 어떤 부분이 병목 현상인지, 즉 어떤 스레드가 가장 바쁜지 조사하는 것입니다.
프로파일링의 목적은 최적화 대상으로 병목 현상을 식별하는 것입니다. 추측에 의존하면 병목 현상이 아닌 게임의 일부를 최적화하게 되어 전체 성능에 거의 또는 전혀 개선이 없을 수 있습니다.
일부 "최적화"는 실제로 게임의 전체 성능을 악화시킬 수도 있습니다.
전체 CPU 워크로드가 병목 현상인 경우는 드뭅니다. 현대 CPU는 독립적으로 동시에 작업을 수행할 수 있는 여러 코어를 가지고 있습니다. 각 CPU 코어에서 다른 스레드가 실행될 수 있습니다.
완전한 Unity 애플리케이션은 다양한 목적으로 여러 스레드를 사용하지만, 성능 문제를 찾는 데 가장 일반적인 스레드는 다음과 같습니다:

  • 메인 스레드: 이는 모든 게임 로직/스크립트가 기본적으로 작업을 수행하는 곳이며, 물리, 애니메이션, UI, 렌더링과 같은 기능

및 시스템에 대해 대부분의 시간이 소요됩니다.

  • 렌더 스레드: 렌더링 과정에서 메인 스레드는

장면을 검사하고 카메라 컬링, 깊이 정렬, 드로우 콜 배칭을 수행하여 렌더링할 항목 목록을 생성합니다. 이 목록은 렌더 스레드로 전달되어 Unity의 내부 플랫폼 독립적 표현에서 특정 플랫폼에서 GPU에 지시하는 데 필요한 특정 그래픽 API 호출로 변환됩니다.

  • 작업 워커 스레드: 개발자는 C# 작업 시스템을 활용하여 특정 종류의 작업을 워커 스레드에서 실행하도록 예약할 수 있으며, 이는 메인 스레드의 작업량을 줄입니다. Unity의 일부 시스템과 기능도 물리, 애니메이션, 렌더링과 같은 작업 시스템을 활용합니다.

메인 스레드

아래 이미지는 메인 스레드에 바인딩된 프로젝트의 모습을 보여줍니다. 이 프로젝트는 Meta Quest 2에서 실행 중이며, 일반적으로 VR 기기에서 멀미를 방지하기 위해 높은 프레임 속도가 중요하기 때문에 13.88ms(72fps) 또는 8.33ms(120fps)의 프레임 예산을 목표로 합니다. 그러나 이 게임이 30fps를 목표로 하더라도 이 프로젝트에 문제가 있음이 분명합니다.

렌더 스레드와 워커 스레드가 프레임 예산 내에 있는 예제와 유사해 보이지만, 메인 스레드는 전체 프레임 동안 명백히 작업으로 바쁜 상태입니다. 프레임 끝에 있는 약간의 프로파일러 오버헤드를 감안하더라도, 메인 스레드는 45ms 이상 동안 바쁘게 작동하고 있어 이 프로젝트의 프레임 속도는 22fps 미만입니다. 메인 스레드가 VSync를 기다리는 유휴 상태를 나타내는 마커가 없으며, 전체 프레임 동안 바쁘게 동작합니다.
다음 조사 단계는 프레임에서 가장 오래 걸리는 부분을 식별하고 그 이유를 이해하는 것입니다. 이 프레임에서 PostLateUpdate.FinishFrameRendering은 16.23ms가 소요되며, 이는 전체 프레임 예산보다 더 많은 시간입니다.
자세히 살펴보면 Inl_RenderCameraStack이라는 마커가 다섯 번 나타나는데, 이는 다섯 개의 카메라가 활성화되어 장면을 렌더링하고 있음을 나타냅니다. Unity의 모든 카메라는 컬링, 정렬, 배칭을 포함한 전체 렌더 파이프라인을 호출하므로, 이 프로젝트에서 가장 우선순위가 높은 작업은 활성 카메라 수를 줄이는 것이며, 이상적으로는 하나만 사용하는 것입니다.
모든 MonoBehaviour Update() 메서드를 포함하는 BehaviourUpdate 마커는 7.27ms가 소요되며, 타임라인의 자홍색 섹션은 스크립트가 관리되는 힙 메모리를 할당하는 곳을 나타냅니다. 계층 구조 뷰로 전환하고 GC.Alloc을 검색 창에 입력하여 필터링하면 이 프레임에서 메모리 할당에 약 0.33ms가 소요됨을 보여줍니다. 그러나 이는 메모리 할당이 CPU 성능에 미치는 영향에 대한 부정확한 측정입니다.
GC.Alloc 마커는 실제로 시작부터 종료 지점까지의 시간을 측정하여 타이밍되지 않습니다. 오버헤드를 최소화하기 위해 시작 타임스탬프와 할당 크기만 기록됩니다. 프로파일러는 이들이 보이도록 최소한의 시간을 할당합니다. 실제 할당은 특히 시스템에서 새로운 메모리 범위를 요청해야 할 때 더 오래 걸릴 수 있습니다. 영향을 더 명확하게 보려면, 할당을 수행하는 코드 주위에 프로파일러 마커를 배치하고, 딥 프로파일링에서 타임라인 뷰의 자홍색 GC.Alloc 샘플 사이의 간격은 얼마나 시간이 걸렸는지에 대한 일부 표시를 제공합니다.
또한, 새 메모리를 할당하면 측정하고 직접 귀속시키기 어려운 성능에 부정적인 영향을 미칠 수 있습니다:

  • 시스템에서 새 메모리를 요청하면 모바일 기기의 전력 예산에 영향을 미쳐 시스템이 CPU나 GPU를 느리게 할 수 있습니다.
  • 새 메모리는 CPU의 L1 캐시에 로드되어 기존 캐시 라인을 밀어낼 가능성이 있습니다.
  • 점진적 또는 동기식 가비지 컬렉션은 관리된 메모리의 기존 여유 공간이 결국 초과됨에 따라 직접 또는 지연되어 트리거될 수 있습니다.

프레임 시작 시, 네 개의 Physics.FixedUpdate 인스턴스가 총 4.57ms를 차지합니다. 이후에, LateBehaviourUpdate(MonoBehaviour.LateUpdate() 호출)가 4ms가 소요되고, 애니메이터는 약 1ms를 차지합니다.
이 프로젝트가 원하는 프레임 예산과 속도를 달성하려면, 이러한 모든 메인 스레드 이슈를 조사하여 적절한 최적화를 찾아야 합니다. 가장 큰 성능 향상은 가장 오랜 시간이 걸리는 부분을 최적화함으로써 이루어질 것입니다.
메인 스레드에 바인딩된 프로젝트에서 최적화를 위해 살펴볼 만한 영역은 다음과 같습니다:

  • 물리
  • MonoBehaviour 스크립트 업데이트
  • 가비지 할당 및/또는 컬렉션
  • 카메라 컬링 및 렌더링
  • 효율이 낮은 드로우 콜 배칭
  • UI 업데이트, 레이아웃 및 리빌드
  • 애니메이션

조사하려는 문제에 따라 다른 도구도 도움이 될 수 있습니다:

  • 오래 걸리지만 정확한 이유를 보여주지 않는 MonoBehaviour 스크립트의 경우, 코드에 프로파일러 마커를 추가하거나 프로파일링을 시도하여 전체 호출 스택을 확인하세요.
  • 관리된 메모리를 할당하는 스크립트의 경우, 할당 호출 스택을 활성화하여 할당이 어디에서 오는지 정확히 확인하세요. 또는 딥 프로파일링을 활성화하거나 프로젝트 감사기를 사용하여 메모리별로 필터링된 코드 이슈를 확인하여 관리된 할당을 초래하는 모든 코드 라인을 식별할 수 있습니다.
  • 효율이 낮은 드로우 콜 배칭의 원인을 조사하려면 프레임 디버거를 사용하세요.

렌더 스레드

다음은 렌더 스레드에 바인딩된 프로젝트입니다. 이는 아이소메트릭 시점을 가진 콘솔 게임으로, 33.33ms의 목표 프레임 예산을 가지고 있습니다.

프로파일러 캡처는 현재 프레임에서 렌더링이 시작되기 전에, 메인 스레드가 Gfx.WaitForPresentOnGfxThread 마커로 표시된 것처럼 렌더 스레드를 기다리고 있음을 보여줍니다.
렌더 스레드는 여전히 이전 프레임의 드로우 콜 명령을 제출하고 있으며 메인 스레드로부터 새로운 드로우 콜을 받을 준비가 되어 있지 않습니다. 렌더 스레드는 Camera.Render에 시간을 소비하고 있습니다.
현재 프레임과 관련된 마커와 다른 프레임의 마커를 구분할 수 있는데, 후자는 더 어둡게 표시됩니다. 또한 메인 스레드가 계속 진행하여 렌더 스레드가 처리할 드로우 콜을 발행하기 시작하면, 렌더 스레드가 현재 프레임을 처리하는 데 100ms 이상 소요되어 다음 프레임에서도 병목 현상을 일으키는 것을 볼 수 있습니다.
추가 조사 결과, 이 게임은 9개의 다른 카메라와 대체 셰이더로 인한 많은 추가 패스를 포함하는 복잡한 렌더링 설정을 가지고 있었습니다. 또한 이 게임은 포워드 렌더링 경로를 사용하여 130개 이상의 포인트 라이트를 렌더링하고 있었는데, 이는 각 라이트마다 여러 개의 추가 투명 드로우 콜을 발생시킬 수 있습니다. 총합하면, 이러한 문제들이 결합되어 프레임당 3000개 이상의 드로우 콜을 생성했습니다.
렌더 스레드에 바인딩된 프로젝트를 조사할 때 일반적인 원인은 다음과 같습니다:

  • 특히 OpenGL이나 DirectX 11과 같은 구형 그래픽 API에서 드로우 콜 배칭이 비효율적인 경우
  • 너무 많은 카메라. 분할 화면 멀티플레이어 게임을 만들지 않는 한, 활성 카메라는 하나만 있어야 합니다.
  • 컬링이 비효율적이어서 너무 많은 것들이 그려지는 경우. 카메라의 프러스텀 크기와 컬 레이어 마스크를 조사하세요. 오클루전 컬링 활성화를 고려하세요. 월드에서 객체가 배치되는 방식에 대해 알고 있는 정보를 기반으로 간단한 오클루전 컬링 시스템을 직접 만드는 것도 고려해 보세요. 씬에 그림자를 생성하는 객체가 얼마나 많은지 확인하세요 - 그림자 컬링은 '일반' 컬링과는 별도의 패스에서 발생합니다.

렌더링 프로파일러 모듈은 매 프레임마다 드로우 콜 배치 수와 SetPass 호출 수에 대한 개요를 보여줍니다. 렌더 스레드가 GPU에 발행하는 드로우 콜 배치를 조사하기 위한 최고의 도구는 프레임 디버거입니다.

워커 스레드

메인이나 렌더 스레드 이외의 CPU 스레드에 바인딩된 프로젝트는 그리 흔하지 않습니다. 그러나 프로젝트가 데이터 지향
기술 스택(DOTS)을 사용하는 경우, 특히 C# 잡 시스템을 사용하여 작업이 메인 스레드에서 워커 스레드로 이동된 경우에 발생할 수 있습니다.
다음은 에디터의 플레이 모드에서 캡처한 것으로, CPU에서 파티클 유체 시뮬레이션을 실행하는 DOTS 프로젝트를 보여줍니다.

언뜻 보기에는 성공처럼 보입니다. 워커 스레드에 Burst 컴파일된 작업들이 빽빽하게 채워져 있어 대량의 작업이 메인 스레드에서 분리되었음을 나타냅니다. 일반적으로 이는 올바른 결정입니다.
그러나 이 경우, 48.14ms의 프레임 시간과 메인 스레드에서
35.57ms의 회색 WaitForJobGroupID 마커는 문제가 있음을 보여줍니다. WaitForJobGroupID는 메인 스레드가 워커 스레드에서 비동기적으로 실행할 작업을 예약했지만, 워커 스레드가 이러한 작업을 완료하기 전에 그 결과가 필요하다는 것을 나타냅니다.
WaitForJobGroupID 아래의 파란색 프로파일러 마커는 메인 스레드가 대기하는 동안 작업을 실행하여 작업이 더 빨리 완료되도록 시도하고 있음을 보여줍니다.
Burst 컴파일된 작업이라도 여전히 많은 처리를 수행하고 있습니다. 아마도 이 프로젝트에서 서로 가까이 있는 파티클을 빠르게 찾기 위해 사용하는 공간 쿼리 구조를 최적화하거나 더 효율적인 구조로 교체해야 할 수도 있습니다. 또는 공간 쿼리 작업을 프레임의 시작이 아닌 끝에 예약하고, 결과는 다음 프레임 시작까지 필요하지 않도록 할 수 있습니다. 아마도 이 프로젝트는 너무 많은 파티클을 시뮬레이션하려고 시도하고 있을 수 있습니다. 추가적인
작업 코드 분석이 해결책을 찾는 데 필요하므로, 더 세분화된 프로파일러 마커를 추가하면 가장 느린 부분을 식별하는 데 도움이 됩니다.
프로젝트의 작업이 이 예제처럼 병렬화되지 않을 수도 있습니다. 아마도 단일 워커 스레드에서 실행되는 하나의 긴 작업만 있을 수 있습니다. 작업이 예약된 시간과 완료되어야 하는 시간 사이에
충분한 시간이 있다면 괜찮습니다. 그렇지 않으면, 위 스크린샷처럼 메인 스레드가 작업이 완료될 때까지 대기하며 지연되는 것을 볼 수 있습니다.
동기화 지점과 워커 스레드 병목 현상의 일반적인 원인은 다음과 같습니다:

  • Burst 컴파일러로 컴파일되지 않은 작업
  • 여러 워커 스레드에 걸쳐 병렬화되지 않고 단일 워커 스레드에서 오래 실행되는 작업
  • 작업이 예약된 프레임 지점과 결과가 필요한 지점 사이의 시간이 충분하지 않음
  • 프레임 내에서 모든 작업이 즉시 완료되어야 하는 여러 "동기화 지점"

CPU 사용량 프로파일러 모듈의 타임라인 뷰에 있는 플로우 이벤트 기능을 사용하여 작업이 언제 예약되고 메인 스레드에서 결과가 언제 필요한지 조사할 수 있습니다. 효율적인 DOTS 코드 작성에 대한 자세한 내용은 DOTS 모범 사례 가이드를 참조하세요.

GPU 바운드

메인 스레드가 Gfx.WaitForPresentOnGfxThread와 같은 프로파일러 마커에 많은 시간을 소비하고, 렌더 스레드가 동시에 Gfx.PresentFrame이나
<GraphicsAPIName>.WaitForLastPresent와 같은 마커를 표시한다면 애플리케이션은 GPU에 바인딩되어 있습니다.
다음 캡처는 Vulkan 그래픽 API를 사용하는 삼성 갤럭시 S7에서 촬영되었습니다. 이 예제에서 Gfx.PresentFrame에 소비된 시간 중 일부는 VSync 대기와 관련이 있을 수 있지만, 이
프로파일러 마커의 극단적인 길이는 대부분의 시간이 GPU가 이전 프레임 렌더링을 완료하기를 기다리는 데 소비되고 있음을 나타냅니다.

이 게임에서는 특정 게임플레이 이벤트가 GPU에서 렌더링되는 드로우 콜 수를 세 배로 증가시키는 셰이더 사용을 유발했습니다. GPU 성능을 프로파일링할 때 조사해야 할 일반적인 문제는 다음과 같습니다:

  • 앰비언트 오클루전과 블룸과 같은 일반적인 원인을 포함한 비용이 많이 드는 전체 화면 후처리 효과
  • 다음과 같은 이유로 비용이 많이 드는 프래그먼트 셰이더:
    • 분기 로직
    • 하프 정밀도 대신 전체 부동 소수점 정밀도 사용
    • GPU의 웨이브프론트 점유율에 영향을 미치는 레지스터의 과도한 사용
  • 비효율적인 UI, 파티클 시스템 또는 후처리 효과로 인한 투명 렌더 큐에서의 오버드로우
  • 4K 디스플레이나 모바일 기기의 레티나 디스플레이와 같은 지나치게 높은 화면 해상도
  • 조밀한 메시 지오메트리나 LOD 부족으로 인한 마이크로 삼각형, 이는 모바일 GPU에서 특히 문제가 되지만 PC 및 콘솔

GPU에도 영향을 미칠 수 있습니다

  • 압축되지 않은 텍스처나 밉맵이 없는 고해상도 텍스처로 인한 캐시 미스 및 GPU 메모리 대역폭 낭비
  • 동적 그림자가 활성화된 경우 프레임당 여러 번 실행될 수 있는 지오메트리 또는 테셀레이션 셰이더

애플리케이션이 GPU 바운드로 보이는 경우, 프레임 디버거를 사용하여 GPU로 전송되는 드로우 콜 배치를 빠르게 이해할 수 있습니다. 그러나 이 도구는 특정 GPU 타이밍 정보를 제공하지 않고, 전체 장면이 어떻게 구성되는지만 보여줍니다.
GPU 병목 현상의 원인을 조사하는 가장 좋은 방법은 적절한 GPU 프로파일러에서 GPU 캡처를 검사하는 것입니다. 사용할 도구는 대상 하드웨어와 선택된 그래픽 API에 따라 달라집니다. 자세한 내용은 이 가이드의 프로파일링 및 디버깅 도구 섹션을 참조하세요.

메모리 프로파일링

메모리 프로파일링은 런타임 성능과 크게 관련이 없습니다. 하드웨어 플랫폼 메모리 제한을 테스트하거나 게임이 충돌하는 경우에 유용합니다.
또한 실제로 메모리 사용량을 증가시키는 변경을 통해 CPU/GPU 성능을 개선하려는 경우에도 관련이 있을 수 있습니다.
Unity에서 애플리케이션의 메모리 사용량을 분석하는 두 가지 방법이 있습니다.
메모리 프로파일러 모듈: 이것은 애플리케이션이 메모리를 사용하는 위치에 대한 기본 정보를 제공하는 내장 프로파일러 모듈입니다.
메모리 프로파일러 패키지: 이것은 프로젝트에 추가할 수 있는 Unity 패키지입니다. Unity 에디터에 추가적인 메모리 프로파일러 창을 추가하여 애플리케이션의 메모리 사용량을 더 자세히 분석할 수 있습니다. 스냅샷을 저장하고 비교하여 메모리 누수를 찾거나 메모리 레이아웃을 확인하여 메모리 단편화 문제를 찾을 수 있습니다.
이러한 내장 도구를 사용하면 메모리 사용량을 모니터링하고, 예상보다 메모리 사용량이 높은 애플리케이션 영역을 찾고, 메모리 단편화를 찾아 개선할 수 있습니다.
이 섹션에서는 Unity의 메모리 프로파일링 도구에 대한 간략한 소개를 제공합니다. 자세한 설명은 Unity 프로파일링 및 디버그 도구 섹션을 참조하세요.

메모리 예산 이해 및 정의

대상 장치의 메모리 제한을 이해하고 예산을 세우는 것은 멀티플랫폼 개발에 중요합니다. 장면과 레벨을 설계할 때 각 대상 장치에 대해 설정된 메모리 예산을 준수하세요. 제한과 가이드라인을 설정함으로써 애플리케이션이 각 플랫폼 하드웨어 사양의 제약 내에서 잘 작동하도록 보장할 수 있습니다.
개발자 문서에서 장치 메모리 사양을 찾을 수 있습니다. 예를 들어,Xbox One 콘솔은 문서에 따르면 포그라운드에서 실행되는 게임에 대해 최대 5GB의 가용 메모리로 제한됩니다.
메시 및 셰이더 복잡성, 텍스처 압축에 대한 콘텐츠 예산을 설정하는 것도 유용할 수 있습니다. 이 모든 것이 할당되는 메모리의 양에 영향을 미칩니다. 이러한 예산 수치는 프로젝트의 개발 주기 동안 참조될 수 있습니다.

물리적 RAM 한계 결정

각 대상 플랫폼에는 메모리 제한이 있으며, 이를 알면 애플리케이션에 대한 메모리 예산을 설정할 수 있습니다. 메모리 프로파일러를 사용하여 캡처 스냅샷을 확인하세요. 하드웨어 리소스(아래 이미지 참조)는 물리적 램(RAM)과 비디오 램(VRAM) 크기를 보여줍니다. 이 수치는 모든 공간이 사용 가능하지 않을 수 있다는 사실을 고려하지 않습니다. 그러나 작업을 시작하는 데 유용한 대략적인 수치를 제공합니다.
여기에 표시된 수치가 항상 전체 그림을 보여주지 않을 수 있으므로 대상 플랫폼에 대한 하드웨어 사양을 교차 참조하는 것이 좋습니다. 개발 키트 하드웨어는 때때로 더 많은 메모리를 가지고 있거나, 통합 메모리 아키텍처를 가진 하드웨어로 작업할 수 있습니다.

하드웨어 리소스에는 스냅샷이 캡처된 디바이스 RAM 및 VRAM 수치가 표시됩니다.ALT

각 대상 플랫폼에 대한 최저 사양 결정

지원하는 각 플랫폼에 대해 RAM 측면에서 가장 낮은 사양의 하드웨어를 식별하고, 이를 메모리 예산 결정의 지침으로 사용하세요. 모든 물리적 메모리가 사용 가능하지 않을 수 있음을 기억하세요. 예를 들어, 콘솔은 이전 게임을 지원하기 위해 하이퍼바이저를 실행하고 있을 수 있으며, 이는 전체 메모리의 일부를 사용할 수 있습니다. 총 메모리의 일정 비율(예:
80%)을 사용하는 것을 고려하세요. 모바일 플랫폼의 경우, 고사양 기기에서 더 나은 품질과 기능을 지원하기 위해 여러 단계의 사양으로 나누는 것도 고려할 수 있습니다.

대규모 팀을 위한 팀별 예산 고려

메모리 예산을 정의한 후에는 팀별 메모리 예산 설정을 고려하세요. 예를 들어, 환경 아티스트에게는 로드되는 각 레벨이나 장면에 사용할 일정량의 메모리를
할당하고, 오디오 팀에게는 음악과 음향 효과를 위한 메모리 할당을 제공하는 식입니다.
프로젝트가 진행됨에 따라 예산을 유연하게 조정하는 것이 중요합니다. 한 팀이 예산을 크게 밑돌면, 그 여유분을 다른 팀에 할당하여 개발 중인 게임 영역을 개선할 수 있습니다.
대상 플랫폼에 대한 메모리 예산을 결정하고 설정한 후, 다음 단계는 프로파일링 도구를 사용하여 게임의 메모리 사용량을 모니터링하고 추적하는 것입니다.

메모리 프로파일러 모듈의 간단 및 상세 보기

메모리 프로파일러 모듈은 간단 보기와 상세 보기라는 두 가지 보기를 제공합니다. 간단 보기를 사용하여 애플리케이션의 메모리 사용량에 대한 상위 수준 보기를 얻으세요.
필요한 경우, 상세 보기로 전환하여 더 자세히 살펴볼 수 있습니다.

메모리 프로파일러 모듈을 사용하여 에셋 및 씬 오브젝트 메모리 할당과 관련된 정보를 빠르게 수집할 수 있습니다.

간단 보기

총 사용 메모리 수치는 "Unity 메모리에서 추적한 총량"입니다. 여기에는 Unity가 예약한 메모리(총 예약 메모리 수치)가 포함되지 않습니다.
시스템 사용 메모리 수치는 OS가 애플리케이션에서 사용 중인 것으로 간주하는 메모리입니다. 이 수치가 0으로 표시되면, 프로파일링 중인 플랫폼에서 프로파일러 카운터가 구현되지 않았음을 의미합니다. 이 경우 의존할 수 있는 최선의 지표는 총 예약 메모리입니다. 이러한 경우 자세한 메모리 정보를 위해 네이티브 플랫폼 프로파일링 도구로 전환하는 것이 좋습니다.

상세 보기

실행 파일, DLL 및 Mono 가상 머신이 사용하는 메모리 양을 조사하려면 프레임별 메모리 수치만으로는 충분하지 않습니다. 이러한 종류의 메모리 분석을 위해서는 상세 스냅샷 캡처를 사용하세요.

캡처한 샘플을 사용하여 실행 파일 및 DLL 메모리 사용량과 같은 자세한 정보를 검사합니다.
참고: 메모리 프로파일러 모듈의 상세 보기에서 참조 트리는 네이티브 참조만 표시합니다. UnityEngine.Object에서 상속받은 유형의 객체 참조는 관리되는 셸의 이름으로 표시될 수 있습니다.

하지만 이러한 참조는 그 아래에 네이티브 객체가 있기 때문에만 표시될 수 있습니다. 반드시 모든 관리되는 유형이 표시되지는 않습니다. 예를 들어, 필드 중 하나에 Texture2D 참조가 있는 객체의 경우, 이 보기에서는 어떤 필드가 해당 참조를 보유하고 있는지 볼 수 없습니다. 이러한 종류의 세부 정보를 위해서는 메모리 프로파일러 패키지를 사용하세요.

플랫폼 예산에 메모리 사용량이 얼마나 근접하는지 개괄적으로 파악하려면 다음과 같은 '대략적인' 계산을 사용하세요:
시스템 사용 메모리 (또는 시스템 사용이 0으로 표시될 경우 총 예약 메모리)

  • 추적되지 않는 메모리의 대략적인 버퍼 / 플랫폼 총 메모리

이 수치가 플랫폼 메모리 예산의 100%에 근접하기 시작하면, 메모리 프로파일러 패키지를 사용하여 원인을 파악하세요.

메모리 프로파일러 패키지를 이용한 심층 분석

메모리 프로파일러 패키지는 더욱 상세한 메모리 분석에 유용합니다. 이를 사용하여 스냅샷을 저장하고 비교함으로써 메모리 누수를 찾거나 애플리케이션의 메모리 레이아웃을 확인하여 최적화할 영역을 찾을 수 있습니다.
메모리 프로파일러 패키지의 큰 장점 중 하나는 네이티브 객체를 캡처하는 것 외에도(메모리 프로파일러 모듈처럼), 관리되는 메모리를 볼 수 있고, 스냅샷을 저장하고 비교하며, 메모리 사용량의 시각적 분석과 함께 더욱 상세하게 메모리 내용을 탐색할 수 있다는 점입니다.

메모리 프로파일러에 대한 자세한 내용은 Unity 프로파일링 및 디버그 도구 섹션에서 확인하세요.
또는 메모리 프로파일러 모듈의 상세 보기를 사용하여 가장 많은 메모리를 사용하는 트리를 탐색하여 무엇이 가장 많은 메모리를 사용하고 있는지 찾을 수 있습니다.

메모리 프로파일러 모듈을 사용하면 에셋과 씬 오브젝트를 드릴다운하여 활용도가 가장 높은 오브젝트를 쉽게 찾을 수 있습니다.

메모리 프로파일러 모듈의 많은 기능이 메모리 프로파일러 패키지로 대체되었지만, 여전히 모듈을 사용하여 메모리 분석 작업을 보완할 수 있습니다.
예시:

  • GC 할당 감지: 모듈에서도 확인 가능하지만, Project Auditor를 사용하면 더 쉽게 추적할 수 있습니다.
  • 힙의 사용/예약 크기 빠르게 확인: 최신 버전의 메모리 프로파일러 모듈에서 이 정보를 보여줍니다.
  • 쉐이더 메모리 분석: 최신 버전의 메모리 프로파일러 모듈에서 보고됩니다.

이 섹션의 앞부분에서 언급했듯이, 메모리 예산을 설정할 때는 전체 대상 플랫폼 중 사양이 가장 낮은 기기에서 프로파일링해야 함을 기억하세요. 목표 제한을 염두에 두고 메모리 사용량을 면밀히 모니터링하세요.
일반적으로 메모리가 많은 강력한 개발 시스템을 사용하여 프로파일링하는 것이 좋습니다(큰 메모리 스냅샷을 저장하거나 빠르게 로드하고 저장하는 공간이 중요합니다).
메모리 프로파일링은 CPU 및 GPU 프로파일링과 비교하여 추가 메모리 오버헤드를 발생시킬 수 있다는 점에서 다릅니다. 메모리 프로파일링은 더 높은 사양의 기기(더 많은 메모리가 있는)에서 수행해야 할 수도 있지만, 특히 낮은 사양의 대상 기기에 대한 메모리 예산 제한에 주의해야 합니다.
메모리 사용량 프로파일링 시 고려해야 할 사항:

  • 품질 수준, 그래픽 티어 및 에셋 번들 변형과 같은 설정은

더 강력한 기기에서 다른 메모리 사용량을 가질 수 있습니다. 예를 들어:

  • 품질 수준 및 그래픽 설정은 그림자 맵에 사용되는 렌더 텍스처의 크기에 영향을 줄 수 있습니다.
  • 해상도 스케일링은 화면 버퍼, 렌더 텍스처 및 후처리 효과의 크기에 영향을 줄 수 있습니다.
  • 텍스처 품질 설정은 모든 텍스처의 크기에 영향을 줄 수 있습니다.
  • 최대 LOD는 모델 등에 영향을 줄 수 있습니다.
  • HD(고화질)와 SD(표준 화질) 버전과 같은 에셋 번들 변형이 있고 기기 사양에 따라 사용할 변형을 선택하는 경우, 프로파일링하는 기기에 따라 에셋 크기가 달라질 수 있습니다.
  • 대상 기기의 화면 해상도는 후처리 효과에 사용되는 렌더 텍스처의 크기에 영향을 줍니다.
  • 기기의 지원 그래픽 API는 API에서 지원하는 쉐이더 변형에 따라 쉐이더 크기에 영향을 줄 수 있습니다.
  • 다양한 품질 설정, 그래픽 티어 설정 및 에셋 번들 변형을 사용하는 계층화된 시스템을 갖추면 더 넓은 범위의 기기를 대상으로 할 수 있습니다. 예를 들어, 4GB 모바일 기기에는 에셋 번들의 고화질 버전을 로드하고, 표준 화질 버전을 2GB 기기에 로드할 수 있습니다. 그러나 위의 메모리 사용량 변형을 염두에 두고 두 유형의 기기뿐만 아니라 화면 해상도나 지원되는 그래픽 API가 다른 기기도 테스트해야 합니다.
참고: 유니티 에디터는 에디터와 프로파일러에서 로드되는 추가 객체들로 인해 일반적으로 항상 더 큰 메모리 사용량을 보여줍니다.

 

유니티 프로파일링과 디버그 툴

이 섹션에서는 유니티에서 사용 가능한 각 프로파일링 및 디버그 도구의 기능에 대해 더 자세히 살펴봅니다.

도구 차이점에 관한 참고 사항

이 섹션에서 언급된 일부 도구는 Frame Debugger와 같은 디버깅 도구와 같은 다른 카테고리에 속합니다. 기술적으로 프로파일러는 아니지만, 유니티 프로젝트를 분석하고 개선할 때 도구 모음에 포함하는 것이 중요합니다.
프로파일링, 디버깅 및 정적 분석 도구 간의 차이점은 다음과 같습니다.

  • 프로파일링 도구는 코드 실행과 관련된 타이밍 데이터를 계측하고 수집합니다.
  • 디버깅 도구는 프로그램 실행을 단계별로 진행하고, 값을 검사하기 위해 일시 중지하며, 다른 많은 고급 기능을 제공합니다. 예를 들어, Frame Debugger를 사용하면 프레임 렌더링을 단계별로 진행하고, 쉐이더 값 등을 검사할 수 있습니다.
  • 정적 분석기는 소스 코드나 다른 에셋을 입력으로 받아 내장된 규칙을 사용하여 해당 입력의

"정확성"에 대해 프로젝트를 실행할 필요 없이 분석하는 프로그램입니다.
 

프로파일러

유니티 프로파일러는 런타임에 병목 현상이나 멈춤 현상의 원인을 감지하고 특정 프레임이나 시점에서 무슨 일이 일어나고 있는지 더 잘 이해하는 데 도움이 됩니다.
유니티의 프로파일링은 계측 기반으로, 많은 프로파일러 마커 데이터를 제공합니다. 에디터에서 직접 프로파일링하면 일부 오버헤드가 추가되어 결과가 왜곡될 수 있다는 점에 유의하세요. 마찬가지로, 개발 머신이 대상 기기보다 훨씬 더 강력할 가능성이 높습니다.
작업하려는 프로파일러 모듈만 활성화하거나 독립 실행형 프로파일러를 사용하세요. 이는 더 깨끗한 프로파일링 데이터와 감소된 프로파일링 오버헤드와 같은 이점을 제공합니다.
일반적으로 CPU, 메모리 및 렌더러 모듈을 항상 활성화하는 것이 유용합니다. 필요에 따라 오디오 및 물리학과 같은 다른 프로파일러 모듈을 활성화하세요.

유니티 프로파일링 시작하기

유니티 프로파일러를 시작하려면 다음 단계를 따르세요:

  • 프로파일링 시 개발 빌드를 사용해야 합니다. 파일 > 빌드 설정 > 개발 빌드 선택을 통해 이를 수행하세요.
  • 자동 연결 프로파일러 체크박스를 선택하세요(선택 사항).
  • 참고: 자동 연결 프로파일러는 초기 시작 시간에 최대 10초를 추가할 수 있으며, 첫 번째

씬의 초기화를 프로파일링하려는 경우에만 활성화해야 합니다. 자동 연결 프로파일러를 활성화하지 않으면 실행 중인 개발 빌드에 수동으로 프로파일러를 연결할 수 있습니다.

  • 대상 플랫폼용으로 빌드하세요.
  • 창 > 분석 > 프로파일러를 통해 유니티 프로파일러를 여세요.
  • 필요하지 않은 프로파일러 모듈을 비활성화하세요. 활성화된 각 모듈은 플레이어에 성능 오버헤드를 발생시킵니다. (Profiler.CollectGlobalStats 마커를 사용하여 이 오버헤드의 일부를 관찰할 수 있습니다).
  • 기기 모바일 네트워크를 비활성화하고 WiFi를 활성화된 상태로 두세요.
  • 대상 기기에서 빌드를 실행하세요.
    • 자동 연결 프로파일러를 선택한 경우, 빌드에는 에디터 머신의 IP 주소가 내장됩니다. 시작 시 애플리케이션은 이 IP 주소에서 유니티 프로파일러에 직접 연결을 시도합니다. 프로파일러가 자동으로 연결되고 프레임 및 프로파일링

정보를 표시하기 시작합니다.

  • 자동 연결 프로파일러를 선택하지 않은 경우,

대상 선택 드롭다운을 사용하여 플레이어에 수동으로 연결해야 합니다.

빌드 시간을 절약하기 위해(정확도는 다소 떨어짐), 유니티 에디터에서 직접 실행되는 애플리케이션을 프로파일링할 수 있습니다. 프로파일러 창에서 'Attach to Player' 드롭다운 메뉴에서 'Playmode'를 선택하세요.

프로파일러 팁

CPU 사용량 프로파일러 모듈에서 VSync 및 기타 카테고리 비활성화

VSync 마커는 CPU 메인 스레드가 VSync를 기다리는 동안 발생하는 "유휴 시간"을 나타냅니다. 마커를 숨기면 다른 카테고리 시간이 어떻게 형성되었는지, 또는 총 프레임 시간이 어떻게 구성되었는지 이해하기 어려울 수 있습니다. 이를 고려하여 또 다른 옵션은 VSync를 목록 최상단에 재정렬하는 것입니다. 이렇게 하면 VSync 마커에 의해 추가된 "노이즈"가 줄어들어 전체 그래프를 더 명확하게 볼 수 있습니다.
기타(Others) 마커는 프로파일링 오버헤드를 나타내며, 프로젝트의 최종 빌드에는 존재하지 않으므로 안전하게 무시할 수 있습니다.

빌드에서 VSync 비활성화

메인 스레드, 렌더 스레드 및 GPU가 어떻게 상호작용하는지 명확한 그림을 얻는 또 다른 방법은 VSync가 완전히 비활성화된 빌드를 프로파일링하는 것입니다. **편집 > 프로젝트 설정...**으로 이동한 다음 품질을 선택하고 대상 기기에 사용할 품질 수준을 클릭하여 VSync 카운트를 '동기화 안 함'으로 설정하세요.
게임의 개발 빌드를 만들고 프로파일러를 연결하세요. 다음 VBlank를 기다리는 대신, 게임은 이전 프레임이 완료되는 즉시 새 프레임을 시작합니다. VSync를 비활성화하면 일부 플랫폼에서 티어링과 같은 시각적 결함이 발생할 수 있지만(이 경우 릴리스 빌드에서는 다시 활성화하는 것을 잊지 마세요), 인위적인 대기 시간을 제거하면 프로젝트의 병목 현상이 어디에 있는지 조사할 때 프로파일러 캡처를 더 쉽게 읽을 수 있습니다.

플레이모드 또는 에디터 모드에서 프로파일링하는 시기 파악

프로파일러를 사용할 때 플레이어 대상으로 플레이모드, 에디터 또는 원격/연결된 기기를 선택할 수 있습니다.
게임/애플리케이션을 프로파일링할 때는 플레이모드를, 게임을 둘러싼 Unity 에디터가 무엇을 하고 있는지 보려면 에디터 모드를 사용하세요.
프로파일링 대상으로 에디터를 사용하면 프로파일링 정확도에 큰 영향을 미칩니다. 프로파일러 창이 자기 자신을 재귀적으로 프로파일링하기 때문입니다. 그러나 에디터 성능이 저하되면 에디터를 프로파일링하는 것이 유용할 수 있습니다. 이렇게 하면 에디터 속도를 저하시키고 생산성을 방해하는 스크립트와 확장 프로그램을 식별할 수 있습니다.

에디터를 프로파일링하고 싶은 예시:

  • 플레이 버튼을 누른 후 플레이 모드로 들어가는 데 시간이 오래 걸리는 경우
  • 에디터가 느려지고 응답하지 않는 경우
  • 프로젝트를 여는 데 시간이 오래 걸리는 경우. "에셋 데이터베이스를 더 효과적으로 사용하기 위한 팁" 블로그 게시물에서는
  • profiler-enable 명령줄 옵션을 사용하여 에디터가 실행되는 순간부터

프로파일링을 시작하는 방법을 설명합니다.
독립 실행형 프로파일러 사용하기
독립 실행형 프로파일러를 사용하세요. 이 방식에서는 플레이 모드나 에디터 프로파일링을 수행하고자 할 때
프로파일러가 유니티 에디터와 별개의 새로운 프로세스로 실행됩니다. 이렇게 하면 프로파일러 UI나 에디터가 측정된 타이밍에 영향을 미치는 것을 방지할 수 있습니다. 또한 필터링하고 작업하기에 더 깔끔한 프로파일링 데이터를 얻을 수 있습니다.

빠른 반복 작업을 위한 에디터 내 프로파일링
성능 문제를 빠르게 반복적으로 수정하고 싶을 때는 에디터 내에서 프로파일링하세요.
예를 들어, 빌드에서 성능 문제가 발견되면 에디터에서도 동일한 문제가 나타나는지 확인하기 위해 프로파일링을 수행하세요. 문제를 발견했다면,
플레이 모드 프로파일링을 사용하여 잠재적 해결책을 향해 빠르게 변경 작업을 반복하세요.
문제가 해결되면 빌드를 만들고 대상 기기에서도 해결책이 제대로 작동하는지 확인하세요.
이 워크플로우는 변경 사항을 빌드하고 기기에 배포하는 데 소요되는 시간을 줄일 수 있어 최적의 방법입니다. 대신, 에디터에서 빠르게 반복 작업을 수행하고 프로파일링 도구를 사용하여 변경 결과를 검증할 수 있습니다.
다음은 Unity 프로파일러의 추가 사용 사례와 기능을 탐색하는 데 도움이 되는 리소스입니다:

프레임 디버거

프레임 디버거는 특정 프레임에서 실행 중인 게임의 재생을 일시 중지하고 렌더링에 사용된 개별 드로우 콜을 볼 수 있게 함으로써 렌더링을 최적화하는 데 도움을 줍니다.
이 도구를 사용하면 드로우 콜 목록을 하나씩 단계별로 살펴볼 수 있어, 장면을 구성하는 그래픽 요소들이 프레임을 어떻게 형성하는지 확인할 수 있습니다.
프레임 디버거의 한 가지 장점은 드로우 콜이 GameObject의 형상에 해당하는 경우, 해당 객체가 메인 계층 구조 패널에서 강조 표시되어 식별을 돕는다는 점입니다.
또한 프레임 디버거는 프레임별로 렌더링 순서를 분석하여 오버드로우를 테스트하는 데에도 사용할 수 있습니다. 자세한 내용은 아래의 최적화 팁을 참조하세요.

Window > Analysis > Frame Debugger 메뉴에서 프레임 디버거를 엽니다.
에디터나 디바이스에서 애플리케이션이 실행 중일 때 활성화(Enable)를 클릭하세요. 이렇게 하면 애플리케이션이 일시 중지되고 현재 프레임의 모든 드로우 콜이 프레임 디버그 창 왼쪽에 순서대로 나열됩니다. 프레임버퍼 클리어 이벤트와 같은 추가 세부 정보도 포함됩니다.

프레임 디버거 창에는 왼쪽 아래에 드로우 호출과 이벤트가 나열되고 슬라이더를 사용하여 각 이벤트를 시각적으로 살펴볼 수 있습니다.

디버거 창 상단의 슬라이더를 사용하면 드로우 콜을 빠르게 스크롤하여 관심 있는 항목을 신속하게 찾을 수 있습니다.
Unity는 그래픽 API에 드로우 콜을 발행하여 화면에 기하학적 도형을 그립니다. 드로우 콜은 그래픽 API에게 무엇을 어떻게 그릴지 알려줍니다. 각 드로우 콜에는 텍스처, 쉐이더, 버퍼와 같은 그래픽 API가 필요로 하는 모든 정보가 포함됩니다. 종종 드로우 콜 자체보다 드로우 콜을 준비하는 과정이 더 많은 리소스를 소모합니다.
이 준비 과정은 "렌더 상태"라고 알려진 것으로 그룹화됩니다. 이 영역에서 성능을 최적화하는 한 가지 방법은 이러한 렌더 상태 변경의 수를 줄이는 것입니다.
프레임 디버거는 드로우 콜이 어디에서 발생하는지 식별하는 데 도움이 됩니다. 렌더링 프로세스를 시각화하고 이해하여 렌더 상태 변경을 줄이기 위해 드로우 콜을 그룹화하는 방법에 대한 결정을 내리는 데 활용하세요.

게임 창에는 프레임 디버거에서 선택한 드로 콜(포스트 프로세싱 효과 적용이 끝날 무렵)까지 구성된 씬 프레임이 표시됩니다.ALT

프레임 디버거의 목록 계층을 참조하여 관심 있는 드로우 콜이 어디에서 발생하는지 찾을 수 있습니다. 목록에서 항목을 선택하면 게임 창에서 해당 드로우 콜까지 포함하여 장면이 어떻게 나타나는지 볼 수 있습니다.
목록 계층 오른쪽에 있는 패널은 기하학적 세부 정보와 렌더링에 사용된 쉐이더와 같은 각 드로우 콜에 대한 정보를 제공합니다.
이 외에도 드로우 콜이 이전 콜과 배칭되지 않은 이유와 쉐이더에 입력된 정확한 속성 값에 대한 검토와 같은 유용한 정보도 제공됩니다.

드로 콜을 선택하면 해당 셰이더, 배치에서 제외된 이유, 셰이더 속성 값을 보여주는 세부 정보가 모두 세부 정보 영역에 표시됩니다.

쉐이더 속성 값과 함께 ShaderProperties 섹션에서는 해당 쉐이더가 어떤 쉐이더 단계에서 사용되었는지도 보여줍니다(예: vertex(정점), fragment(프래그먼트), geometry(지오메트리), hull(헐), domain(도메인)).

셰이더 스테이지는 셰이더 프로퍼티 세부 정보 섹션에서 확인할 수 있습니다.

원격 프레임 디버깅

지원되는 플랫폼에서는 프레임 디버거를 원격 플레이어에 연결할 수 있습니다(WebGL은 지원되지 않음). 데스크톱 플랫폼의 경우, 빌드에서 '백그라운드에서 실행'을 활성화하세요.
원격 프레임 디버깅을 설정하는 방법:

  • 대상 플랫폼에 프로젝트의 표준 빌드를 생성합니다('개발 플레이어' 선택).
  • 플레이어를 실행합니다.
  • 에디터에서 프레임 디버그 창을 엽니다.
  • 플레이어 선택 드롭다운을 클릭하고 실행 중인 활성 플레이어를 선택합니다.
  • 활성화를 클릭합니다.

이제 프레임 디버그 목록 계층에서 드로우 콜과 이벤트를 단계별로 살펴보고 활성 플레이어에서 결과를 관찰할 수 있습니다.

리모컨에 연결된 프레임 디버그 창 플레이어 빌드

렌더 타겟 표시 옵션

원격 플레이어 빌드에 연결된 프레임 디버그 창.
프레임 디버그 창에는 게임 뷰의 현재 상태에서 빨간색, 녹색, 파란색 및 알파 채널을 분리할 수 있는 툴바가 있습니다.
채널 버튼 오른쪽에 있는 레벨 슬라이더를 사용하여 밝기 수준에 따라 뷰의 영역을 분리할 수 있습니다. 이 컨트롤은 RenderTexture로 렌더링할 때 활성화됩니다.
여러 렌더 타겟에 동시에 렌더링할 때는 RenderTarget 드롭다운 목록을 사용하여 게임 뷰에 표시할 대상을 선택할 수 있습니다.

프레임 디버그는 타깃 뎁스 채널 컨트롤을 렌더링합니다.

드롭다운 목록에는 깊이 버퍼의 내용을 표시하는 '깊이(Depth)' 옵션도 있습니다.

프레임 디버그 창으로 뎁스 버퍼 내용 보기

일반적인 문제에 대한 5가지 렌더링 최적화

다음 팁과 요령을 사용하여 프레임 디버거와 기타 렌더 디버그 도구로 식별할 수 있는 일반적인 렌더링 성능 문제를 최적화하세요.
먼저 성능 병목 현상을 파악하세요
시작하려면 GPU 부하가 높은 프레임을 찾으세요. 대부분의 플랫폼은 CPU와 GPU 모두에서 프로젝트 성능을 분석하기 위한 강력한 도구를 제공합니다. 예를 들어 Arm 하드웨어/Mali GPU용 Arm Mobile Studio, Microsoft Xbox용 PIX, Sony PlayStation용 Razor, Apple iOS용 Xcode Instruments 등이 있습니다.
해당 네이티브 프로파일러를 사용하여 프레임 비용을 특정 부분으로 분석하세요. 이것이 그래픽 성능을 향상시키기 위한 출발점입니다.

This view was GPU-bound on a PS4 Pro at roughly 45 ms per frame

드로우 콜 최적화

PC와 현재 세대의 콘솔 하드웨어는 많은 드로우 콜을 처리할 수 있지만, 각 호출의 오버헤드는 여전히 충분히 높아서 이를 줄이려는 노력이 필요합니다.
모바일 기기에서는 드로우 콜 최적화가 매우 중요합니다. 이는 드로우 콜 배칭을 통해 달성할 수 있습니다.
프레임 디버거를 사용하여 최적의 그룹화와 배칭을 위해 재구성할 수 있는 드로우 콜을 식별하세요. 이 도구는 특정 드로우 콜이 배칭되지 않는 이유를 파악하는 데도 도움이 됩니다.
드로우 콜 배치를 줄이는 데 도움이 되는 기술에는 다음이 포함됩니다:

  • 오클루전 컬링: 전경 객체 뒤에 숨겨진 객체를 제거하고 오버드로우를 줄입니다. 이는 추가적인 CPU 처리가 필요하므로, 프로파일러를 사용하여 GPU에서 CPU로 작업을 이동하는 것이 유익한지 확인하세요.
  • GPU 인스턴싱: 동일한 메시와 재질을 공유하는 많은 객체가 있는 경우 배치를 줄일 수 있습니다. 장면에서 제한된 수의 모델을 사용하면 성능이 향상됩니다. 예술적으로 잘 수행된다면, 반복적으로 보이지 않게 복잡한 장면을 구축할 수 있습니다.
  • SRP 배처: 바인드 및 드로우 GPU 명령을 배칭하여 드로우 콜 간의 GPU 설정을 줄일 수 있습니다. SRP 배칭의 이점을 얻으려면 필요한 만큼 많은 재질을 사용하되, 호환 가능한 셰이더 변형의 수를 제한하세요. 예를 들어, 유니버설 렌더 파이프라인(URP)과 고화질 렌더 파이프라인(HDRP)의 Lit 및 Unlit 셰이더를 사용하되,

키워드 조합 간의 변형을 최소화하세요.

오버드로우 감소를 통한 필 레이트 최적화

오버드로우는 애플리케이션이 GPU가 처리할 수 있는 것보다 더 많은 픽셀을 프레임당 그리려고 시도하고 있음을 나타낼 수 있습니다. 성능뿐만 아니라,
모바일 기기의 발열과 배터리 수명도 영향을 받습니다. Unity가 렌더링 전에 객체를 정렬하는 방식을 이해함으로써 오버드로우를 줄일 수 있습니다.
내장 렌더 파이프라인은 렌더링 모드렌더큐에 따라 게임오브젝트를 정렬합니다. 각 객체의 셰이더는 이를 렌더 큐에 배치하며, 이는 종종 그리기 순서를 결정합니다.

객체가 서로 겹쳐 렌더링되면 오버드로우가 발생합니다. 내장 렌더 파이프라인을 사용하는 경우, 씬 뷰 컨트롤 바를 사용하여 오버드로우를 시각화할 수 있습니다. 드로우 모드를 오버드로우로 전환하세요.
밝은 픽셀은 객체가 서로 겹쳐 그려지는 부분을 나타내며, 어두운 픽셀은 오버드로우가 적은 부분을 의미합니다.

HDRP는 렌더 큐를 약간 다르게 제어합니다. 이 접근 방식을 더 자세히 이해하려면 렌더러 및 재질 우선순위 섹션을 읽어보세요.
HDRP에는 오버드로우를 식별할 수 있는 도구가 포함되어 있습니다. HDRP 게임에서
오버드로우를 찾으려면 Window > Render Pipeline
> Render Pipeline Debug를 통해 렌더 파이프라인 디버그 도구를 사용하세요.
렌더링 섹션으로 이동하여 전체 화면 디버그 모드를 TransparencyOverdraw로 변경하세요.
이 디버그 옵션은 각 픽셀을 히트맵으로 표시합니다. 투명 픽셀이 없는 검은색부터 파란색, 그리고 최대 픽셀 비용 수의 투명 픽셀을 나타내는 빨간색까지 색상이 다양합니다.

전체 화면 디버그 모드에서 TransparencyOverdraw를 활성화하면 씬에서 오버드로를 찾을 수 있습니다.

이 모드를 활성화하면 애플리케이션의 장면과 영역을 플레이하면서 오버드로우가 많은 부분을 확인할 수 있습니다.

HDRP 및 전체 화면 디버그 모드로 오버드로 시각화하기

가장 비용이 많이 드는 셰이더 검사

이것은 깊은 주제이지만, 일반적으로 가능한 한 셰이더 복잡성을 줄이는 것을 목표로 하세요. 여기서 쉽게 얻을 수 있는 성과는 가능한 경우 정밀도를 줄이는 것입니다. 예를 들어, 반정밀도 부동 소수점 변수를 사용할 수 있다면 사용하세요. 또한 대상 플랫폼에 대한 웨이브프론트 점유율과 건강한 점유율을 얻기 위해 GPU 프로파일링 도구를 사용하는 방법에 대해 알아볼 수 있습니다.

렌더링을 위한 멀티코어 최적화

Player Settings > Other Settings에서 Graphics Jobs를 활성화하여 PlayStation과 Xbox의 멀티코어 프로세서를 활용하세요. Graphics Jobs를 사용하면 Unity가 렌더링 작업을 여러 CPU 코어에 분산시켜 렌더 스레드의 부담을 줄일 수 있습니다. 자세한 내용은 멀티스레드 렌더링 및 그래픽 작업
튜토리얼을 참조하세요.

포스트 프로세싱 효과 프로파일링

포스트 프로세싱 에셋이 대상 플랫폼에 최적화되어 있는지 확인하세요. Asset Store의 도구 중 PC 게임용으로 원래 제작된 것들은 콘솔이나 모바일 기기에서 필요 이상의 리소스를 소비할 수 있습니다. 대상 플랫폼의 네이티브 프로파일러 도구를 사용하여 프로파일링하세요. 모바일이나 콘솔 대상용 포스트 프로세싱 효과를 직접 제작할 때는 가능한 한 간단하게 유지하세요.
프레임 디버깅 및 분석을 위한 다양한 도구가 있습니다. 더 많은 아이디어를 얻으려면 프로파일링 및 디버그 도구 색인을 확인해보세요.
Unity 프레임 디버거에 대해 더 자세히 알아보려면 다음 리소스를 참조하세요:

프로파일 분석기

표준 Unity 프로파일러는 단일 프레임 분석을 수행할 수 있지만, 프로파일 분석기는 Unity 프로파일러 프레임 세트에서 캡처한 프로파일링 마커 데이터를 집계하고 시각화할 수 있습니다.
프로파일 분석기를 시작하려면:

  • Window > Package Manager를 통해 프로파일 분석기 패키지를 설치하세요.

프로파일 분석기 사용 시, 성능 최적화 작업 전후를 비교하기 위해 프로파일링 세션을 저장하는 것이 좋은 접근 방식입니다.

패키지 관리자에서 프로필 분석기 설치

프로파일 분석기는 Unity 프로파일러에서 캡처한 프레임 세트를 가져와 통계 분석을 수행합니다. 이 데이터는 각 함수에 대한 최소, 최대, 평균 및 중간값과 같은 유용한 성능 타이밍 정보를 생성하여 표시됩니다.
개발 중 문제 및 최적화 질문에 답하는 데 도움이 됩니다. 성능 차이를 확인하기 위한 게임 시나리오의 A/B 테스트, 코드 리팩토링 및 최적화, 새로운 기능 또는 Unity 버전 업그레이드 전후의 프로파일링 데이터를 비교하는 데 사용할 수 있습니다.

프로파일 분석기는 프로파일링 세션에서 캡처한 여러 프레임을 집계하고 비교하는 데 사용할 수 있는 Unity 프로파일러의 훌륭한 동반자입니다.

프로파일 분석기의 단일 뷰에서 집계 데이터 보기를 사용하면 시간에 따른 고수준 성능 질문에 즉시 답할 수 있습니다. 이것은
한 번에 하나의 프레임만 보는 것보다 데이터를 보는 더 좋은 방법입니다. 예를 들어, 300프레임(10초) 게임플레이 캡처나 20초 로딩 시퀀스에서:

  • 메인 스레드와 렌더 스레드에서 가장 큰 CPU 비용은 무엇인가요?
  • 각 마커의 평균/중간값/총 비용은 얼마인가요?

이러한 질문에 대한 답변은 가장 큰 문제가 어디에 있는지, 최적화 시 무엇을 우선시해야 하는지 파악하는 데 필수적입니다.
프로파일 분석기에서 제공하는 통계와 세부 정보를 통해 여러 프레임에 걸쳐 실행되는 코드의 성능 특성을 더 깊이 파악하거나, 이전 프로파일 캡처 세션과 비교할 수 있습니다.

프로필 분석기 기본 창 개요

프로파일 분석기는 프로파일링 데이터를 분석하기 위한 여러 뷰와 접근 방식을 제공합니다. 프로파일링 데이터 세트를 선택, 정렬, 보기 및 비교하기 위한 패널로 구분되어 있습니다.

프레임 컨트롤 패널은 프레임 또는 프레임 범위를 선택하는 데 사용됩니다. 선택하면 마커 세부 정보 창이 업데이트되어 선택 항목에 대한 집계 데이터와 유용한 통계가 포함된 정렬 가능한 마커 목록이 표시됩니다. 마커 요약 창은 선택한 마커에 대한 심층 정보를 표시합니다. 목록의 각 마커는 선택한 프레임 범위의 모든 필터링된 스레드에서 해당 마커의 모든 인스턴스를 집계한 것입니다.
 
뒷 부분 조금 남았는데... 2부에서...