Unity 프로파일러는 애플리케이션의 성능을 분석하고 개선하는 데 사용할 수 있는 툴입니다. 프로파일러는 애플리케이션의 네이티브 Unity 코드와 관리되는 코드의 함수 호출에 대한 프레임 시간 분석을 수행합니다. ProfilerMarker API를 사용하여 자체 코드에 타이밍 마커를 삽입하면 애플리케이션의 특정 영역에 대한 성능을 더욱 자세히 파악할 수 있습니다.
로우 레벨 네이티브 플러그인 프로파일러 API를 사용하여 프로파일러를 확장하고 네이티브 플러그인 코드의 성능을 프로파일링하거나, 또는 Razor(PS4), PIX(Xbox, Windows), Chrome Tracing, ETW, ITT, Vtune, Telemetry 등의 타사 프로파일링 툴로 전송할 프로파일링 데이터를 준비할 수 있습니다. 로우 레벨 네이티브 플러그인 프로파일러 API는 Unity 프로파일러와 외부 툴 간의 통신을 위해 다음의 인터페이스를 제공합니다.
IUnityProfiler 플러그인 API를 사용하여 네이티브 플러그인의 C/C++ 코드에 계측을 추가합니다.
플러그인 API는 IUnityProfiler.h
헤더에서 선언된 IUnityProfiler 인터페이스로 표시됩니다. Unity는 이 헤더를 Unity 설치의 <UnityInstallPath>\Editor\Data\PluginAPI
폴더에 저장합니다. (macOS에서는 Unity 애플리케이션을 마우스 오른쪽 버튼으로 클릭한 후 Show Package Contents를 선택하십시오. 헤더는 Contents\PluginAPI
에 있습니다.)
메서드 | 설명 |
---|---|
CreateMarker |
명명된 계측 범위를 나타내는 프로파일러 마커를 만듭니다. 이 마커는 계측 샘플을 생성하는 데 사용할 수 있습니다. |
SetMarkerMetadataName |
프로파일러 마커에 대한 계측 샘플과 함께 전달할 수 있는 커스텀 파라미터 이름을 지정합니다. |
BeginSample |
프로파일러 마커의 이름을 따라 명명한 코드의 계측 섹션을 시작합니다. |
EndSample |
계측 섹션을 종료합니다. |
EmitEvent |
메타데이터가 포함된 일반 이벤트를 방출합니다. |
IsEnabled |
프로파일러가 데이터를 캡처하는 경우 1을 반환합니다. |
IsAvailable |
프로파일러를 사용할 수 있는 에디터 또는 개발 플레이어의 경우 1을 반환하고, 릴리스 플레이어의 경우 0을 반환합니다. |
RegisterThread |
지정된 이름으로 현재 스레드를 등록합니다. |
UnregisterThread |
프로파일러에서 현재 스레드의 등록을 해제합니다. |
이 예제는 프로파일러 창에 표시되는 프로파일러 이벤트를 생성합니다.
# include <IUnityInterface.h>
# include <IUnityProfiler.h>
static IUnityProfiler* s_UnityProfiler = NULL;
static const UnityProfilerMarkerDesc* s_MyPluginMarker = NULL;
static bool s_IsDevelopmentBuild = false;
static void MyPluginWorkMethod()
{
if (s_IsDevelopmentBuild)
s_UnityProfiler->BeginSample(s_MyPluginMarker);
// Code I want to see in Unity Profiler as "MyPluginMethod".
// ...
if (s_IsDevelopmentBuild)
s_UnityProfiler->EndSample(s_MyPluginMarker);
}
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginLoad(IUnityInterfaces* unityInterfaces)
{
s_UnityProfiler = unityInterfaces->Get<IUnityProfiler>();
if (s_UnityProfiler == NULL)
return;
s_IsDevelopmentBuild = s_UnityProfiler->IsAvailable() != 0;
s_UnityProfiler->CreateMarker(&s_MyPluginMarker, "MyPluginMethod", kUnityProfilerCategoryOther, kUnityProfilerMarkerFlagDefault, 0);
}
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginUnload()
{
s_UnityProfiler = NULL;
}
네이티브 프로파일러 플러그인 API는 Unity 보조 시스템과 타사 프로파일링 API 간의 인터페이스를 제공합니다. 이를 통해 외부 프로파일링 툴을 사용하여 Unity 애플리케이션을 프로파일링할 수 있습니다. IUnityProfilerCallbacks 헤더가 이 API를 노출하며, Unity는 이 API를 Unity 설치의 <UnityInstallPath>\Editor\Data\PluginAPI
폴더에 저장합니다. (macOS에서는 Unity 애플리케이션을 마우스 오른쪽 버튼으로 클릭한 후 Show Package Contents를 선택하십시오. 헤더는 Contents\PluginAPI
에 있습니다.)
다음 Unity 프로파일러 기능을 사용하면 애플리케이션의 성능을 분석하는 데 도움이 되는 계측 데이터를 캡처할 수 있습니다.
프로파일러 기능 | 설명 |
---|---|
카테고리 | Unity는 프로파일 데이터를 카테고리(예: 렌더링, 스크립팅, 애니메이션)로 그룹화한 후 각 카테고리에 컬러를 할당합니다. 카테고리에 컬러를 할당하면 프로파일러 창에서 데이터 타입을 시각적으로 쉽게 구분할 수 있습니다. 프로파일러 네이티브 플러그인 API를 이용하면 이러한 컬러를 검색해서 가져온 후 외부 프로파일링 툴에서 사용할 수 있습니다. |
사용 플래그 | 사용 플래그는 Unity가 외부 프로파일링 툴로 전송하는 데이터의 양을 줄이는 필터 역할을 합니다. 사용 플래그를 사용하면 Unity가 외부 툴로 전송하기 전에 프로파일링 데이터에서 불필요한 정보를 제거할 수 있습니다. 프로파일러는 데이터 필터링을 위해 이벤트 마커에 다음의 사용 플래그를 적용합니다. 유효성 플래그 - Unity 에디터, 개발 플레이어 또는 릴리스 플레이어에서 마커의 이용 가능 여부를 나타내는 플래그입니다. 상세도 수준 - 에디터에서 수행하는 작업 타입과 관련되며, 작업에 필요한 정보 레벨(예: 내부, 디버그 또는 사용자 수준)입니다. |
프레임 이벤트 | 프로파일러 네이티브 플러그인 API를 사용하면 외부 프로파일링 툴에서 프레임 시간 분석을 수행할 수 있습니다. |
스레드 프로파일링 | Unity는 스레드(예: 메인 스레드, 렌더 스레드 및 작업 시스템 워커 스레드)에 대해 상당한 양의 작업을 수행합니다. 프로파일러 네이티브 플러그인 API를 사용하면 모든 스레드에 대한 프로파일링을 활성화할 수 있습니다. |
Unity 프로파일러가 외부 프로파일러에서 생성하는 계측 데이터를 사용하려면 타사 프로파일러를 통합하는 C/C++ 플러그인 코드에서 다음의 최소 콜백 집합을 사용하십시오.
콜백 | 기능 |
---|---|
RegisterCreateCategoryCallback |
IUnityProfilerCreateCategoryCallback 콜백을 등록하여 Unity가 카테고리를 생성할 때마다 프로파일러 카테고리 이름과 컬러를 가져옵니다. |
RegisterCreateMarkerCallback |
Unity가 마커를 생성할 때마다 호출되는 IUnityProfilerCreateMarkerCallback 콜백을 등록합니다. 이 콜백을 사용하여 마커의 이름, 프로파일러 카테고리 및 사용 플래그를 가져오십시오. 콜백 함수의 const UnityProfilerMarkerDesc* markerDesc 파라미터는 RegisterMarkerEventCallback 에서 마커를 필터링하는 데 사용할 수 있는 마커 설명의 영구 포인터를 나타냅니다. |
RegisterMarkerEventCallback |
싱글샷, 범위 지정, 메모리 할당 또는 가비지 컬렉션 이벤트가 발생할 때 Unity가 호출하는 IUnityProfilerMarkerEventCallback 콜백을 등록합니다. 이 콜백을 사용하여 외부 프로파일링 툴에서 관련 함수를 호출할 수 있습니다. 참고: Unity는 GC.Alloc 마커로 메모리 할당 이벤트를 나타내고, GC.Collect 마커로 가비지 컬렉션 이벤트를 나타냅니다. |
RegisterFrameCallback |
프레임을 사용하지 않는 외부 프로파일링 툴이 샘플을 사용할 수 있도록 샘플을 논리 프레임으로 캡슐화합니다. 또한 Unity가 다음 논리 CPU 프레임을 시작할 때 Unity 프로파일러가 실행하는 콜백도 등록합니다. |
RegisterCreateThreadCallback |
Unity가 프로파일링을 위해 스레드를 등록할 때마다 내부 스레드 이름을 가져오는 콜백을 등록합니다. |
이 예제는 푸시/표시 시맨틱이 있는 다른 프로파일러에 Unity 프로파일러 이벤트를 전달하는 방법을 보여줍니다. 다음의 두 가지 함수를 제공합니다.
void MyProfilerPushMarker(const char* name)
- 명명된 마커를 푸시합니다.void MyProfilerPopMarker()
- 계측 마커를 표시합니다.다음 예제는 Unity 프로파일러에서 외부 프로파일러로 계측 시작 및 종료 이벤트를 전달하는 데 필요한 최소한의 구현을 제공합니다.
# include <IUnityInterface.h>
# include <IUnityProfilerCallbacks.h>
static IUnityProfilerCallbacks* s_UnityProfilerCallbacks = NULL;
static void UNITY_INTERFACE_API MyProfilerEventCallback(const UnityProfilerMarkerDesc* markerDesc, UnityProfilerMarkerEventType eventType, unsigned short eventDataCount, const UnityProfilerMarkerData* eventData, void* userData)
{
switch (eventType)
{
case kUnityProfilerMarkerEventTypeBegin:
{
MyProfilerPushMarker(markerDesc->name);
break;
}
case kUnityProfilerMarkerEventTypeEnd:
{
MyProfilerPopMarker();
break;
}
}
}
static void UNITY_INTERFACE_API MyProfilerCreateMarkerCallback(const UnityProfilerMarkerDesc* markerDesc, void* userData)
{
s_UnityProfilerCallbacks->RegisterMarkerEventCallback(markerDesc, MyProfilerEventCallback, NULL);
}
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginLoad(IUnityInterfaces* unityInterfaces)
{
s_UnityProfilerCallbacks = unityInterfaces->Get<IUnityProfilerCallbacks>();
s_UnityProfilerCallbacks->RegisterCreateMarkerCallback(&MyProfilerCreateMarkerCallback, NULL);
}
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginUnload()
{
s_UnityProfilerCallbacks->UnregisterCreateMarkerCallback(&MyProfilerCreateMarkerCallback, NULL);
s_UnityProfilerCallbacks->UnregisterMarkerEventCallback(NULL, &MyProfilerEventCallback, NULL);
}
참고: 모든 마커에서 특정 콜백을 등록 해제하려면 첫 번째 파라미터가 null
로 설정된 UnregisterEventCallback
을 실행하십시오.
프레임마다 한 번 마커 콜백을 동적으로 등록하거나 등록 해제할 수 있습니다. 다음 예제는 타사 프로파일 상태에 따라 콜백을 활성화하거나 비활성화하여 프로파일링 오버헤드를 최소화합니다.
| static void UNITY_INTERFACE_API SystraceFrameCallback(void* userData)
{
bool isCapturing = ATrace_isEnabled();
if (isCapturing != s_isCapturing)
{
s_isCapturing = isCapturing;
if (isCapturing)
{
s_UnityProfilerCallbacks->
RegisterCreateMarkerCallback(SystraceCreateEventCallback, NULL);
}
else
{
s_UnityProfilerCallbacks->
UnregisterCreateMarkerCallback(SystraceCreateEventCallback, NULL);
s_UnityProfilerCallbacks->
UnregisterMarkerEventCallback(NULL, SystraceEventCallback, NULL);
}
}
}
참고: 모든 마커에서 특정 콜백을 등록 해제하려면 첫 번째 파라미터가 null
로 설정된 UnregisterEventCallback
을 실행하십시오.
Unity는 유용한 메타데이터가 들어 있는 다음의 특수 마커를 제공합니다.
Profiler.DefaultMarker
는 Unity가 Profiler.BeginSample 및 Profiler.EndSample 이벤트를 위해 예약하는 마커입니다.
위 예시에서 kUnityProfilerMarkerEventTypeBegin eventType
은 Profiler.BeginSample
이벤트에 해당하며, 다음 데이터를 포함합니다.
UnityEngine.Object
인스턴스 ID입니다. 지정된 오브젝트가 없으면 0입니다.Profiler.BeginSample
에 전달되는 UTF16 문자열입니다. 크기는 바이트 단위입니다.GC.Alloc는 가비지 컬렉션 할당에 해당하는 마커입니다. 다음의 데이터를 포함합니다.