인스트루먼트를 사용한 프로파일링

엔터프라이즈 지원팀에서는 iOS 프로젝트를 많이 접하게 됩니다. iOS 개발을 하다 보면 개발자가 게임을 실행하고 "도대체 왜 이렇게 느리게 실행되는 거지?"라는 생각을 하게 되는 경우가 종종 있습니다. 성능 분석을 위한 훌륭한 도구 세트가 시중에 나와 있으며, 그 중 최고의 도구 중 하나가 바로 Instruments입니다. 이 기능을 사용하여 문제를 찾는 방법을 알아보세요!
Instruments 또는 XCode의 디버깅 툴을 사용하려면 개발 빌드 및 스크립트 디버깅 옵션을 선택하지 않은 상태에서 iOS 빌드 타겟용 Unity 프로젝트를 빌드해야 합니다. 그런 다음 릴리스 모드에서 XCode를 사용하여 결과 XCode 프로젝트를 컴파일하고 연결된 iOS 장치에 배포해야 합니다.
악기를 시작한 후(재생 버튼을 길게 누르거나 제품>프로필을 선택), 시간 프로파일러를 선택합니다. 프로파일링 실행을 시작하려면 애플리케이션 선택기에서 빌드된 애플리케이션을 선택한 다음 빨간색 기록 버튼을 누릅니다. 계측기가 연결된 iOS 기기에서 애플리케이션이 실행되고 시간 프로파일러가 원격 분석 기록을 시작합니다. 원격 분석은 계측기 타임라인에 파란색 그래프로 표시됩니다.

P.S. 호출 계층 구조를 정리하려면 세부 정보 창의 왼쪽 하단에 있는 호출 트리 버튼을 눌러 옵션을 표시하고 재귀 평탄화 및 시스템 라이브러리 숨기기를 선택합니다.

메서드 호출 목록이 상품 창의 세부 정보 섹션에 표시됩니다. 각 최상위 메서드 호출은 애플리케이션 내의 스레드를 나타냅니다.
일반적으로 주요 방법은 모든 관리 코드가 포함되어 있으므로 관심 있는 모든 핫스팟의 위치입니다.
메인 메서드를 확장하면 메서드 호출의 심층 트리가 생성됩니다. 주요 분기는 두 가지 방법 사이에 있습니다:
- [startUnity] 및 UnityLoadApplication(이 메서드 이름은 대문자로 표시되기도 합니다).
- PlayerLoop
[startUnity]는 Unity 엔진을 초기화하는 데 소요된 모든 시간이 포함되어 있어 흥미롭습니다. 그 아래에서 UnityLoadApplication이라는 메서드를 찾을 수 있습니다. 시작 시간을 프로파일링할 수 있는 위치는 UnityLoadApplication 아래에 있습니다.

애플리케이션의 멋진 타임슬라이스 프로파일링이 완료되면 프로파일러를 일시 중지하고 트리 확장을 시작합니다. 트리를 아래로 내려가면 왼쪽 열에서 시간(ms)이 줄어드는 것을 확인할 수 있습니다. 여러분이 찾고 있는 것은 시간을 크게 단축할 수 있는 항목입니다. 이곳은 퍼포먼스 핫스팟이 될 것입니다. 하나를 찾으면 코드베이스로 돌아가서 시간이 너무 많이 걸리는 WTF가 진행 중인지 확인할 수 있습니다. 완전히 필요한 작업일 수도 있고, 먼 옛날에 사전 제작 코드를 해킹해서 프로덕션 프로젝트에 적용했을 수도 있고, 아니면... 정말 수많은 이유가 있을 수 있습니다. 이 핫스팟을 수정할지 여부와 방법은 코드베이스를 누구보다 잘 알고 있는 여러분에게 달려 있습니다.
또한 하나의 큰 핫스팟은 없지만 코드베이스의 여러 곳에서 몇 밀리초의 시간 손실로 나타나는 성능 싱크, 즉 광범위하게 분산되어 있는 성능 싱크를 찾는 데에도 기기를 사용할 수 있습니다. 이렇게 하려면 ⌘F를 누르거나 편집 메뉴에서 찾기/찾기...를 클릭하여 표시되는 악기의 기호 검색 상자에 기능의 일부 또는 전체 이름을 입력합니다. 게임플레이의 일부를 프로파일링하는 경우, PlayerLoop를 확장하고 그 아래의 모든 메서드를 접습니다. 시작 시간을 프로파일링하는 경우 UnityLoadApplication을 확장하고 그 아래의 메서드를 축소합니다. 특정 작업에 낭비된 총 밀리초 수는 플레이어루프 또는 UnityLoadApplication에서 소요된 총 시간을 보고 자체 열에 있는 밀리초 수를 빼면 대략적으로 추정할 수 있습니다.
일반적인 방법을 찾아보세요:
- "Box(", "box" 및 "box"- C# 값 박싱이 발생하고 있음을 나타냅니다. 대부분의 박싱 인스턴스는 사소하게 고정되어 있습니다.
- "Concat" - 문자열 연결은 종종 쉽게 최적화됩니다.
- "CreateScriptingArray" - 배열을 반환하는 모든 Unity API는 배열의 새 복사본을 할당합니다. 이러한 메서드 호출을 최소화하세요.
- "반사" - 반사가 느립니다. 이를 사용하여 반사로 인해 손실되는 시간을 추정하고 가능한 경우 이를 제거하세요.
- "FindObjectOfType" - 반복적이거나 불필요한 FindObjectOfType 호출 또는 기타 느린 것으로 알려진 Unity API를 찾으려면 이 기능을 사용합니다.
- "Linq" - Linq 쿼리 작성 및 삭제에 소요되는 시간을 검토하고, 핫스팟을 수동으로 최적화된 방법으로 대체하는 것을 고려하세요.
Instruments를 사용하면 CPU 시간을 프로파일링할 뿐만 아니라 메모리 사용량도 프로파일링할 수 있습니다. 인스트루먼트의 할당 프로파일러는 애플리케이션의 메모리 사용량에 대한 자세한 보기를 제공하는 두 가지 프로브를 제공합니다. 할당 프로브를 사용하면 특정 시간 범위 동안 메모리 내에 상주하는 객체를 검사할 수 있습니다. VM 추적기 프로브를 사용하면 iOS에서 애플리케이션을 강제로 종료해야 하는 시점을 결정하는 데 사용되는 주요 지표인 더티 메모리 힙 크기를 모니터링할 수 있습니다.
도구에서 할당 프로파일러를 선택하면 두 프로브가 동시에 실행됩니다. 평소와 같이 빨간색 기록 버튼을 눌러 프로파일링 실행을 시작합니다.
할당 프로브를 올바르게 설정하려면 다음 설정이 올바른지 확인하세요. 창 하단에서 할당 수명(가운데 옵션)이 생성 및 지속으로 설정되어 있는지 확인합니다. 녹화 옵션(파일 메뉴)에서 해제된 메모리에 대한 이벤트 삭제가 선택되어 있는지 확인합니다.
메모리 동작을 검사하는 데 가장 유용한 디스플레이는 할당 프로브를 사용할 때 기본 디스플레이인 통계 디스플레이입니다. 이 디스플레이에는 타임라인이 표시됩니다. 권장 설정과 함께 사용하면 그래프에 파란색 선이 표시되어 현재 남아 있는 메모리 할당 시간과 크기를 나타냅니다. 이 그래프를 보면 테스트 중인 시나리오를 반복하여 실행 사이에 파란색 선이 남아 있지 않은지 확인하여 오래 지속되거나 누수된 메모리가 있는지 확인할 수 있습니다.
또 다른 유용한 디스플레이는 통화 트리 디스플레이입니다. 할당이 수행되는 코드 줄과 해당 코드 줄이 담당하는 메모리 사용량을 표시합니다. 다음과 같이 세부정보 오른쪽을 클릭하여 표시를 변경할 수 있습니다:

아래에서 테스트 중인 애플리케이션의 전체 메모리 사용량 중 약 25%가 셰이더로 인한 것임을 확인할 수 있습니다. 로딩 스레드에서 셰이더의 위치를 고려할 때, 셰이더는 애플리케이션 시작 시 로드되는 기본 Unity 프로젝트에 번들로 제공되는 표준 셰이더여야 합니다.

이전과 마찬가지로 핫스팟을 식별한 후에는 프로젝트에 따라 핫스팟을 어떻게 활용할지는 전적으로 프로젝트에 달려 있습니다.
여기까지입니다. 계측기에 대한 간단한 가이드입니다. 1000단어 이상, A팀 참조가 없어야 합니다. 지난번처럼 문제를 일으키고 싶지 않습니다. 저작권 위반은 공식적으로 Not Funny™에 해당합니다.
엔터프라이즈 지원팀에서 이러한 가이드를 더 많이 만들고 있으며, 앞으로 몇 달 안에 베스트 프랙티스 가이드의 정식 버전을 게시할 예정입니다!
계획이 완성되면 정말 기쁩니다.
