Version: 2019.3
言語: 日本語
低レベルネイティブプラグインインターフェース
低レベルのネイティブプラグインレンダリング拡張

低レベルのネイティブプラグイン Profiler API

Unity Profiler ネイティブプラグインを使用すると、Razor (PS4)、PIX (Xbox、Windows)、Chrome Tracing、ETW、ITT、Vtune、Telemetry などの外部ツールの分析のためにスクリプトを通して Unity からデータを抽出できます。Unity Profiler はイベントを記録し、Profiler ネイティブプラグイン API はこれらのイベントをサードパーティ製のプロファイリング API からアクセス可能にし、関連する分析ツールに渡します。

以下の Unity Profiler 機能は、パフォーマンス分析のための計装データを取得するのに役立ちます。

  • Categories: Unity はプロファイルデータをカテゴリ (レンダリング、スクリプティング、アニメーションなど) にグループ化し、各カテゴリに色を割り当てます。これにより、Profiler ウィンドウでデータの種類を視覚的に区別するのに役立ちます。Profiler ネイティブプラグイン API を使用すると、これらの色を取得して外部のプロファイラーで使用することができます。

  • Usage flags: Unity Profiler は、以下の使用に関するフラグをイベントマーカーに適用してデータをフィルタリングします。

    • Availability flags は、マーカーが Unity エディターか、開発版プレイヤーか、リリース版プレイヤーで使用可能かを示すフラグ。

    • Verbosity levels はエディターで行っているタスクの種類とタスクが必要とする情報のレベル (例えば、内部、デバッグ、ユーザーレベル) に関連します。

    Usage flag を使用すると、外部ツールに渡す前にデータをフィルタリングして生成されるデータの量を削減します。また、外部ツールのデータをフィルタリングして情報のノイズを削減することができます。

  • Frame events: Profiler ネイティブプラグイン API を使用すると、外部プロファイラーでフレーム時間分析を行うことができます。

  • Thread profiling: Unity は、スレッド (例えば、メインスレッド、レンダースレッド、ジョブシステムワーカースレッド) 上で著しい量の作業を行います。Profiler ネイティブプラグイン API を使用して、すべてのスレッドでプロファイリングを使用できます。

プラグイン API コールバック

ネイティブの Profiler プラグイン API は、Unity のサブシステムとサードパーティプロファイリング API 間のインターフェースを提供します。API は IUnityProfilerCallbacks ヘッダーによってアクセス可能になります。この API は、Unity の インストール時に <UnityInstallPath>\Editor\Data\PluginAPI フォルダーに保存されます。

外部プロファイラーで Unity Profiler が生成する計装データを使用するには、以下の最小限のコールバックを使用します。

  1. RegisterCreateCategoryCallback: Unity がカテゴリを作成するたびに、Profiler はカテゴリ名と色を取得し、このコールバックを登録します。

  2. RegisterCreateMarkerCallback: Unity がマーカーを作成するたびに、Profiler はマーカー名、カテゴリ、使用フラグを取得し、このコールバックを登録します。UnityProfilerMarkerDesc は永続的なポインターで、RegisterMarkerEventCallback のマーカーをフィルタリングするのに使用できます。

  3. RegisterMarkerEventCallback: Unity Profiler の外部プロファイラーのプッシュ/ポップマーカーを追跡し、指定されたマーカーのイベントコールバックを登録します。スコープ内の計装イベントまたは単発イベントが発生すると、Unity Profiler は指定されたコールバックを実行します。メモリ割り当てやガベージコレクションのイベントをマーカーとして追跡することもできます。Unity はこれらのイベントをそれぞれ GC.AllocGC.Collect として表します。

  4. RegisterFrameCallback: フレームの概念を持たない外部プロファイラーで使用するためにサンプルを論理フレームにカプセル化し、Unity が次の論理 CPU フレームを開始するときに Unity Profiler が実行するコールバックを登録します。

  5. RegisterCreateThreadCallback: Unity がプロファイリングのためにスレッドを登録するたびに、Profiler は内部スレッド名を取得し、そのスレッドのコールバックを登録します。

使用例

最低限の使用例

次の例は、begin と end イベントを外部プロファイラーに送信する方法を示しています。

| #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 の例

フレームごとに 1 回づつ、マーカーコールバックを動的に登録および登録解除できます。次の例は、サードパーティのプロファイルの状況に応じて、コールバックを有効または無効にすることによって、プロファイリングのオーバーヘッドを最小化する方法を示しています。

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

注意: コールバックのオーバーヘッドを最小限にするために、キャプチャの間だけコールバックを登録することができます。

Systrace API は、キャプチャが有効かどうかを決定する ATrace_isEnabled API を提供します。これをフレームごとにチェックして、コールバックを動的に有効/無効にすることができます。より高度な使用例については、UnitySystracePlugin リポジトリ を参照してください。

便利なマーカー

Unity には有用なメタデータを含む以下のマーカーがあります。

Profiler.DefaultMarker

Unity が Profiler.BeginSampleProfiler.EndSample イベントのために予約するマーカー。kUnityProfilerMarkerEventTypeBegin eventTypeProfiler.BeginSample イベントに対応し、以下のデータを持ちます。

  • Int32: UnityEngine.Object インスタンスの ID。オブジェクトが指定されていない場合は 0 です。

  • UInt16 array: Profiler.BeginSample に渡されるUTF16 文字列。サイズはバイト数です。

  • UInt32: カテゴリインデックス。

GC.Alloc

ガベージコレクションの割り当てに対応するマーカー。以下のデータが含まれます。

  • Int64: 割り当てのサイズ。

  • 2019–02–14 公開ページ

  • 低レベル Profiler ネイティブプラグインは Unity [2018.3](../Manual/30_search.html?q = newin20183) で追加 NewIn20183

低レベルネイティブプラグインインターフェース
低レベルのネイティブプラグインレンダリング拡張