로우레벨 네이티브 플러그인 인터페이스
로우레벨 네이티브 플러그인 렌더링 확장 기능

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

The Unity 프로파일러 네이티브 플러그인을 사용하면 스크립트를 통해 Unity에서 데이터를 추출한 후 Razor(PS4), PIX(Xbox, Windows), Chrome Tracing, ETW, ITT, Vtune, Telemetry 등과 같은 외부 도구에서 분석할 수 있습니다. Unity 프로파일러는 이벤트를 기록하고, 프로파일러 네이티브 플러그인API은 이러한 이벤트를 타사 프로파일링 API에 노출하여 관련 분석 툴에 전달되도록 만듭니다.

다음의 Unity 프로파일러 기능을 이용하면 성능 분석을 위한 계측 데이터를 간편하게 캡처할 수 있습니다.

  • Categories: Unity는 프로파일 데이터를 카테고리(예: 렌더링, 스크립팅, 애니메이션)로 그룹화한 후 각 카테고리에 컬러를 할당합니다. 이렇게 하면 프로파일러 창에서 데이터 타입을 시각적으로 쉽게 구분할 수 있습니다. 프로파일러 네이티브 플러그인 API를 이용하면 이러한 컬러를 검색해서 가져온 후 외부 프로파일러에서 사용할 수 있습니다.

  • Usage flags: Unity 프로파일러는 효과적인 데이터 필터링을 위해 다음의 사용 플래그를 이벤트 마커에 적용합니다.

    • Unity 에디터나 개발 또는 릴리스 플레이어에서 마커의 이용 가능 여부를 설명하는 유효성 플래그.

    • 에디터에서 수행하는 작업 타입과 관련된 상세도 레벨과 작업에 필요한 정보 레벨(예: 내부, 디버그 또는 사용자 수준).

    사용 플래그를 이용하면 데이터를 필터링한 후에 외부 툴에 전달하기 때문에 생성되는 데이터 양이 줄어들고, 외부 툴에서 데이터를 필터링하여 정보 소음을 줄일 수 있습니다.

  • Frame events: 프로파일러 네이티브 플러그인 API를 이용하면 외부 프로파일러에서 프레임 시간 분석을 할 수 있습니다.

  • Thread profiling: Unity는 스레드(예: 메인 스레드, 렌더 스레드 및 작업 시스템 워커 스레드)에 대해 상당한 양의 작업을 수행합니다. 프로파일러 네이티브 플러그인 API를 사용하면 모든 스레드에 대한 프로파일링을 활성화할 수 있습니다.

플러그인 API 콜백

네이티브 프로파일러 플러그인 API는 Unity 하위 시스템과 타사 프로파일링 API 간의 인터페이스를 제공합니다. 이 API는 IUnityProfilerCallbacks 헤더에서 노출되고, Unity의 <UnityInstallPath>\Editor\Data\PluginAPI 설치 폴더에 저장됩니다.

Unity 프로파일러가 외부 프로파일러에서 생성하는 계측 데이터를 사용하려면 다음의 최소 콜백 집합을 사용하십시오.

  1. RegisterCreateCategoryCallback: Unity가 카테고리를 만들 때마다 프로파일러가 카테고리 이름 및 컬러를 가져오고, 이 콜백을 등록합니다.

  2. RegisterCreateMarkerCallback: Unity가 마커를 만들 때마다 프로파일러가 마커 이름, 카테고리, 사용 플래그를 가져오고, 이 콜백을 등록합니다. UnityProfilerMarkerDesc는 RegisterMarkerEventCallback의 마커를 필터링할 때 사용할 수 있는 영구 포인터를 나타냅니다.

  3. RegisterMarkerEventCallback: Unity 프로파일러 동등물을 사용하여 외부 프로파일러 푸시/팝 마커를 추적하고, 해당 마커에 대한 이벤트 콜백을 등록합니다. 범위로 지정된 계기 이벤트 또는 단일샷 이벤트가 발생하면 Unity 프로파일러가 지정된 콜백을 실행합니다. 또한 메모리 할당과 가비지 컬렉션 이벤트를 마커로 추적할 수도 있습니다. Unity는 이러한 이벤트를 각각 GC.AllocGC.Collect로 나타냅니다.

  4. RegisterFrameCallback: 프레임 개념이 없는 외부 프로파일러에서 사용하기 위해 샘플을 논리 프레임으로 캡슐화하고, Unity가 다음 논리 CPU 프레임을 시작할 때 Unity 프로파일러가 실행하는 콜백을 등록합니다.

  5. RegisterCreateThreadCallback: Unity가 프로파일링용 스레드를 등록할 때마다 프로파일러가 내부 스레드 이름을 가져오고, 이 콜백을 해당 스레드에 대해 등록합니다.

사용 예제

최소 예제

다음 예제는 외부 프로파일러로 이벤트를 보내고 시작하고 종료하는 방법을 보여줍니다.

| #include <IUnityInterface.h>
# include <IUnityProfilerCallbacks.h><br/>
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(markerDesc->name);
            break;
        }
    }
}
static void UNITY_INTERFACE_API MyProfilerCreateEventCallback(
    const UnityProfilerMarkerDesc* markerDesc, void* userData)
{
    s_UnityProfilerCallbacks->
      RegisterEventCallback(markerDesc, MyProfilerEventCallback, NULL);
}
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginLoad(IUnityInterfaces* unityInterfaces)
{
    s_UnityProfilerCallbacks = unityInterfaces->Get<IUnityProfilerCallbacks>();
    s_UnityProfilerCallbacks->
      RegisterCreateEventCallback(&MyProfilerCreateEventCallback, NULL);
}
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginUnload()
{
    s_UnityProfilerCallbacks->
      UnregisterCreateEventCallback(&MyProfilerCreateEventCallback, NULL);
    s_UnityProfilerCallbacks->
      UnregisterEventCallback(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-><br/>              RegisterCreateMarkerCallback(SystraceCreateEventCallback, NULL);
        }
        else
        {
            s_UnityProfilerCallbacks->
              UnregisterCreateMarkerCallback(SystraceCreateEventCallback, NULL);
            s_UnityProfilerCallbacks->
              UnregisterMarkerEventCallback(NULL, SystraceEventCallback, NULL);
        }
    }
}

참고: 콜백 오버헤드를 최소화하기 위해 캡처 기간 동안에만 콜백을 등록할 수도 있습니다.

Systrace API는 캡처가 활성화되었는지 여부를 판단하는 ATrace_isEnabled API를 제공합니다. 프레임마다 이 API를 확인하여 콜백을 동적으로 활성화하거나 비활성화할 수 있습니다. 고급 사용 예제는 UnitySystracePlugin 저장소를 참조하십시오.

유용한 마커

Unity는 유용한 메타데이터가 들어 있는 다음의 마커를 제공합니다.

Profiler.DefaultMarker

Unity가 Profiler.BeginSampleProfiler.EndSample 이벤트에 대해 예약하는 마커입니다. kUnityProfilerMarkerEventTypeBegin eventTypeProfiler.BeginSample에 해당하고 다음의 데이터를 포함합니다.

  • Int32: UnityEngine.Object 인스턴스 ID이며, 지정된 오브젝트가 없으면 0입니다.

  • UInt16 배열: Profiler.BeginSample에 전달되는 UTF16 문자열입니다. 크기는 바이트 단위입니다.

  • UInt32: 카테고리 인덱스입니다.

GC.Alloc

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

  • Int64: 할당 크기입니다.

  • 2019–02–14 편집 리뷰를 거쳐 페이지 게시됨

  • Unity 2018.3에서 로우레벨 프로파일러 네이티브 플러그인 추가됨 NewIn20183

로우레벨 네이티브 플러그인 인터페이스
로우레벨 네이티브 플러그인 렌더링 확장 기능