Unity は、同期と非同期の 2 種類の方法で、テクスチャやメッシュのデータをディスクから読み込み GPU にアップロードします。この 2 つの処理は “同期アップロードパイプライン” と “非同期アップロードパイプライン” と呼ばれます。
Unity が同期型アップロードパイプラインを使用すると、データをロードしてアップロードしている間は、他のタスクを実行できません。これにより、アプリケーションに目に見える一時停止が発生することがあります。Unity が非同期アップロードパイプラインを使用すると、バックグラウンドでデータのロードとアップロードを行いながら、他のタスクを実行できます。
テクスチャやメッシュに対して非同期アップロードパイプラインを使用できる場合、Unity は自動的に非同期アップロードパイプラインを使用します。テクスチャやメッシュに非同期アップロードパイプラインを使用できない場合、Unity は自動的に同期アップロードパイプラインを使用します。
同期アップロードパイプラインと非同期アップロードパイプラインの主な違いは、ビルド時に Unity がデータを保存する場所で、それがランタイムに Unity がデータを読み込む方法に影響します。
同期アップロードパイプラインでは、Unity は、1 つのフレームで、テクスチャやメッシュのメタデータ (ヘッダーデータ) と、テクセル/頂点データ (バイナリデータ) の両方を読み込む必要があります。非同期アップロードパイプラインでは、Unity は 1 つのフレームでヘッダーデータのみをロードする必要があり、その後のフレームでバイナリデータを GPU にストリーミングすることができます。
同期型アップロードパイプラインでは、以下が行われます。
非同期のアップロードパイプラインでは、以下が行われます。
テクスチャは、以下の条件を満たすと、非同期アップロードパイプラインの対象となります。
なお、LoadImage(byte[] data)
を使用してテクスチャをロードする場合、上記の条件が満たされていても、強制的に同期アップロードパイプラインが使用されます。
メッシュは、以下の条件を満たすと、非同期アップロードパイプラインの対象となります。
それ以外の状況では、Unity はテクスチャとメッシュを同期してロードします。
Profiler または他のプロファイリングツールを使用して、スレッドのアクティビティとプロファイラーのマーカーを観察することによって、Unity が非同期アップロードパイプラインを使用していることを特定できます。
以下は、Unity がテクスチャやメッシュのアップロードに非同期アップロードパイプラインを使用していることを示しています。
AsyncUploadManager.ScheduleAsyncRead
、AsyncReadManager.ReadFile
、Async.DirectTextureLoadBegin
プロファイラーマーカー。AsyncRead
スレッドでのアクティビティ。このアクティビティが表示されない場合、Unity は非同期アップロードパイプラインを使用していません。
なお、以下のプロファイラーマーカーは、Unity が非同期アップロードパイプラインを使用していることを示すものではありません。これらは、非同期アップロード作業が必要かどうかをチェックするために呼び出されます。
Initialization.AsyncUploadTimeSlicedUpdate
AsyncUploadManager.AsyncResourceUpload
AsyncUploadManager.ScheduleAsyncCommands
非同期アップロードパイプラインの設定を行うことができます。なお、同期アップロードパイプラインの設定はできません。
Unity では、1 つのリングバッファを再利用して、テクスチャやメッシュデータを GPU にストリーミングします。これにより、必要なメモリ割り当ての数を減らすことができます。
The Async Upload Buffer determines the size of this ring buffer. It has a minimum size of 2 megabytes, and a maximum size of 2047 megabytes.
Unity は、現在ロードしている最大のテクスチャやメッシュに合わせて、自動的にバッファのサイズを変更します。これは時間のかかる操作です。例えば、デフォルトのバッファサイズより大きいテクスチャを多数ロードしている場合など、Unity が複数回実行しなければならない場合は特に時間がかかります。Unity がバッファサイズを変更しなければならない回数を減らすために、この値を、ロードすると予想される最大の値に合わせて設定してください。これは通常、シーン内の最大のテクスチャの値です。
この値は、Quality settings ウィンドウか、QualitySettings.asyncUploadBufferSize API を使用して設定できます。
Async Upload Time Slice は、CPU が GPU にテクスチャやメッシュデータをアップロードするのに費やす時間を、フレームあたりのミリ秒で表したものです。
値が大きいほど、データが GPU 上ですぐに準備できることを意味しますが、CPU はそれらのフレームの間、アップロード操作に多くの時間を費やします。Unity がこの時間をアップロードに使うのは、GPU へのアップロードを待っているデータがバッファにある場合だけです。待機中のデータがなければ、Unity はこの時間を他の操作に使うことができます。
この値は、Quality settings ウィンドウで設定するか、QualitySettings.asyncUploadTimeSlice API を使用して設定できます。
テクスチャやメッシュデータの非同期アップロードの詳細については、Unity ブログの Async Upload Pipeline (AUP) でローディングのパフォーマンスを最適化する を参照してください。