Version: Unity 6.0 (6000.0)
언어 : 한국어
IUnityMemoryManager API 레퍼런스
코드 최적화

로우레벨 네이티브 플러그인 프로파일링

로우레벨 네이티브 플러그인 프로파일러 API를 사용하여 프로파일러를 확장하고 네이티브 플러그인 코드의 성능 데이터를 수집하거나, 프로파일링 데이터를 준비하여 Razor(PS4), PIX(Xbox, Windows), Chrome Tracing, ETW, ITT, Vtune, Telemetry와 같은 타사 프로파일링 툴로 전송할 수 있습니다.

로우레벨 네이티브 플러그인 프로파일러 API는 Unity 프로파일러와 외부 툴링 간 커뮤니케이션을 위해 다음과 같은 인터페이스를 제공합니다.

  • IUnityProfiler: 이 인터페이스를 사용하여 C/C++ 네이티브 플러그인 코드에서 Unity 프로파일러에 계측 이벤트를 추가합니다.
  • IUnityProfilerCallbacks: 이 인터페이스를 사용하여 Unity 프로파일러 이벤트를 인터셉트해서 저장하거나 다른 툴로 리디렉션합니다.

IUnityProfiler API 레퍼런스

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 프로파일러에서 현재 스레드의 등록을 해제합니다.

IUnityProfiler 예시

이 예시는 프로파일러 창에 표시되는 프로파일러 이벤트를 생성합니다.

#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;
}

IUnityProfilerCallbacks API 콜백

네이티브 프로파일러 플러그인 API는 Unity 보조 시스템과 타사 프로파일링 API 간의 인터페이스를 제공하므로 외부 프로파일링 툴을 사용하여 Unity 애플리케이션을 프로파일링할 수 있습니다. IUnityProfilerCallbacks 헤더는 설치된 Unity의 <UnityInstallPath>\Editor\Data\PluginAPI 폴더에 저장되는 API를 표시합니다. macOS에서는 Unity 애플리케이션을 오른쪽 클릭한 후 Show Package Contents를 선택합니다. 헤더는 Contents\PluginAPI에 있습니다.

다음 Unity 프로파일러 기능을 사용하면 애플리케이션의 성능을 분석하는 데 도움이 되는 계측 데이터를 캡처할 수 있습니다.

프로파일러 기능 설명
카테고리 Unity는 프로파일 데이터를 카테고리(예: Rendering, Scripting, Animation)로 그룹화하고 각 카테고리에 컬러를 할당합니다. 컬러로 코딩된 카테고리를 사용하면 프로파일러 창의 데이터 유형을 시각적으로 구분할 수 있습니다. 프로파일러 네이티브 플러그인 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가 프로파일링을 위해 스레드를 등록할 때마다 내부 스레드 이름을 가져오는 콜백을 등록합니다.

IUnityProfilerCallbacks 예시

이 예제는 푸시/표시 시맨틱이 있는 다른 프로파일러에 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을 실행하십시오.

UnitySystracePlugin 예시

프레임마다 한 번 마커 콜백을 동적으로 등록하거나 등록 해제할 수 있습니다. 다음 예제는 타사 프로파일 상태에 따라 콜백을 활성화하거나 비활성화하여 프로파일링 오버헤드를 최소화합니다.

| 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
  • GC.Alloc

Profiler.DefaultMarker

Profiler.DefaultMarker는 Unity가 Profiler.BeginSampleProfiler.EndSample 이벤트에 예약하는 마커입니다.

이전 예제에서 kUnityProfilerMarkerEventTypeBegin eventTypeProfiler.BeginSample 이벤트에 해당하며 다음 데이터를 포함합니다.

  • Int32: UnityEngine.Object 인스턴스 ID입니다. 오브젝트가 지정되어 있지 않으면 0입니다.
  • UInt16 배열: Profiler.BeginSample에 전달되는 UTF16 문자열입니다. 크기는 바이트 단위입니다.
  • UInt32: 카테고리 인덱스입니다.

GC.Alloc

GC.Alloc은 가비지 컬렉션 할당에 해당하는 마커입니다. 다음의 데이터를 포함합니다.

  • Int64: 할당 크기입니다.

추가 리소스

IUnityMemoryManager API 레퍼런스
코드 최적화