テクスチャ ストリーミングのメトリクスのレポート

新しい STAT コマンドを使ってテクスチャ ストリーミングのメトリクスをレポートします。

時点で、STAT STREAMING コンソール コマンドを使ってテクスチャ ストリーミングの統計情報をプロファイリングすることができます。パフォーマンス、メモリの使用、テクスチャ ストリーマーが使用するその他のメトリクスをレポートします。

STAT STREAMING sortby=name maxhistoryframes=1

StatStreaming.png

メモリのデータを読み出す場合、プールという言葉は概念的な (リザーブされた) メモリを表し、実際に使われるメモリに関連付けられてはいません。「ミップ」は、予測つまり将来的な使用ではなく、 現在テクスチャが使用しているメモリにマッピングします。メモリ メトリクスは以下の 3 つのメイン プールに分類されます。

  • Texture

  • Streaming

  • Wanted

これらのプール サイズは、Memory Counters カテゴリの各行の右側にあります。

統計情報

説明

Cycle Counters

Game Thread Update Time

ストリーマー更新の関数が使う時間です。これは、テクスチャ ストリーミングの作業のほとんどを占めます。テクスチャ ストリーマー外部ではテクスチャ、コンポーネント、レベルに対する参照を取り除くなどの少数のタスクだけが処理されます。ゲーム スレッドの更新中、ストリーマーはフル更新に向けてひとつのステップを行います。フル更新はいくつかのフレームを使い、r.Streaming.FramesForFullUpdate に関連しています。統計情報の Counter セクションで定義されているように複数の更新ステップがあります。

Memory Counters

Texture Pool

テクスチャ リソースで利用可能なメモリの合計です。これには、レンダー ターゲット、GPU、パーティクル バッファ、キューブマップ、UI テクスチャ、およびストリーミング不可のテクスチャなど、ストリーミングしないリソースが含まれます。一部のプラットフォームでは、このメモリはスタティックメッシュのようなテクスチャではないリソースを保存するために使用することができます。Texture Pool はほぼ以下と同等になります。 Safety Pool + Temporary Pool + Streaming Pool + NonStreaming Mips (変動分があればその量だけ、セーフティ プールのサイズまで)

Safety Pool

この値は Engine コンフィギュレーション ファイルの [TextureStreaming]MemoryMargin として設定されます。これは、予期しない (ストリーミングしない) 割り当てに対してリザーブします。この値の量によって利用可能なメモリが定期的に変動する場合、テクスチャ ストリーマーはこの変動に対して最大限までストリーミング プールを安定化します。通常の (予測される) 変動がセーフティ プール サイズよりも大きい場合、テクスチャ ストリーマーは常にその配分に適応し、ストリーミング テクスチャのインとアウトのサイクルをできる限り続けます。

Temporary Pool

この値は、r.Streaming.MaxTempMemoryAllowed によって制御され、テクスチャのリサイズ時にストリーマーがどれくらい余分なメモリを使用できるかを指定します。テクスチャのミップカウントを変更する場合、エンジンは新しいテクスチャを作成しなければなりません。このテクスチャはより小さいか、大きいものになり、将来のミップデータを保持します。これは入ってくるリクエスト数を間接的に制御することになります。ストリーマーは、テンポラリ プールが許容する数だけ IO システムにリクエストを送るからです。

テンポラリ プールは少なくともストリーミングする最大リソースと同じ大きさがなければなりませんが、設定を大きくしすぎるとメモリが無駄になります (その目的のためにテンポラリ プールがリザーブされるからです)。一方、設定を小さくしすぎると、ストリーミング速度が遅くなることがあります (IO システムに対して十分な作業を生成せず、アイドル状態にするからです)。ストリーマーは入ってくる複数リクエストの順序に関してほとんど制御しないことにも注意してください。つまり、比較的小さなテンポラリ プールを使うと最初に何をロードするかの制御を強化することができます。

Streaming Pool

テクスチャ ストリーマーが利用できるメモリ量です。ストリーマーは新しいミップのストリーミング、または以前ストリーミングしたミップをできるだけ長くメモリに保持するためにすべての利用可能なメモリを使います。ストリーミング プールには、Visible Mips、Hidden Mips、Force Mips、および Cached Mips が含まれます。Streaming Pool は、ほぼ以下と等しくなります。 Visible Mips* + Hidden Mips + Forced Mips + Cached Mips (*: 十分に使用された場合です。そうでなければ未使用空間を考慮しなければなりません。)

NonStreaming Mips

ストリーミングしないものの割り当てが使うメモリ量です。こうした割り当てが、通常、セーフティ プールの値よりも大きく変動する場合、ストリーミング プールの配分に影響を及ぼすため、回避してください (割り当てを減らすか、セーフティ プールを増やして回避します)。

Required Pool

メトリクスに従いテクスチャ ストリーマーがロードする必要があるミップ データの量です。これはテクスチャ ストリーミング プールの 100% を超えることがあります。その場合、妥協して一部のテキスチャが必要な解像度でロードされなくなります。

Visible Mips

可視テクスチャ ミップが現在必要とするメモリ。強制されたミップは含みません。

Hidden Mips

不可視のテクスチャ ミップで現在使われている必要なメモリ。強制されたミップは含みません。初めてテクスチャが表示されるときに低解像度になるのを防ぐために、ストリーマーは事前にテクスチャをプリストリーミングします。ただし、通常は必要とされるものよりもひとつ低いミップになります (r.Streaming.HiddenPrimitiveScale を参照)。

Forced Mips

強制的にストリームインしたテクスチャが現在使う必要なメモリ。テクスチャは通常ゲームプレイのメカニズムを通して短時間、強制的にストリームインします。これには、non-streamable としてフラグが付いているテクスチャは含みません。

Cached Mips

不要になったテクスチャ ミップが使っているメモリです。そのメモリが他の求められたミップによって必要とされない限り、キャッシュされたままになります。

Wanted Pool

最終的にストリームインされる必要なプールの一部です。

Wanted Mips

求められたプールに実際にどれくらいストリームインされるかです。100% に到達したら、ストリーマーは新しいミップをロードするための IO リクエストの送信を停止します。Wanted Mips = Visible Mips + Hidden Mips + Forced Mips

Inflight Requests

IO によって処理されなければならないメモリがまだどれくらいあるかです。0 の場合は、これまでのすべてのリクエストは新規リクエスト作成時に処理されています。もしこれが、ストリーマーがコンテンツをストリーミング中に起こったら、ストリーマーが利用可能なすべての帯域幅を使用していないことを示しています。r.Streaming.MaxTempMemoryAllowed を増やすことで帯域幅を増やすか (メモリが無駄になり、ロード順の制御が低下することと引き換えに)、r.Streaming.FramesForFullUpdate を減らすことで帯域幅を減らします (更新時間が長くなることと引き換えに)。

IO Bandwidth

最後の更新以降にロードが完了したミップのサイズです。最後の更新以降の時間で割ります。これは IO 帯域幅を正確に測定するものではありませんが、システムがどの程度速くリクエストをロードするかを把握するために使用することができます。

Counters

Setup Async Task

非同期のストリーマー タスクのためにデータを準備するためにかかる時間です。フル更新ループの最初のステップとして実行します。

Update Streaming Data

ストリーミング データをインクリメンタルに更新するためにかかる時間です。これには、可視性のリフレッシュ、テクスチャ ステートの更新、および使用した動的コンポーネントの境界の更新が含まれます。r.Streaming.FramesForFullUpdate によって定義されるように、このステップはいくつかのフレームを連続して実行します。

Streaming Texture

ロードとキャンセルのリクエストを準備し送るためにかかる時間です。

新たにロードしたレベルのインクリメンタルな処理

Unreal Engine 4.15 から、テクスチャ ストリーマーはレベル データをインクリメンタルに処理するようになりました。ロード時と可視になった瞬間の間に各フレームで少しずつ処理します。これまでは、 この処理はレベルが可視になったフレームで起きており、その際に目立つヒッチが生じることがありました。

各フレームで処理される作業量は、r.Streaming.NumStaticComponentsProcessedPerFrame によって制御されます。デフォルト値は 50 です。この値に 0 を設定すると インクリメンタルな作業を無効にし、システムは 4.15 よりも前のように動作します。

重要なこととして、インクリメンタルなレベル処理は、可動性が Static (静的) に設定されているコンポーネントのみに適用されることを覚えておいてください。可動コンポーネントはエンジンのティックで常にインクリメンタルに処理されています。

インクリメンタルな処理が完了したらレベルが可視になるまでそれ以上の処理は不要です。インクリメンタルな処理が完了する前に可視になったら、すべての作業をただちに終了する必要があります。 こうしたことが起こると小さなヒッチが生じる場合があります。

以下のコンソール コマンドを実行してインクリメンタルな処理を調べることができます。

    Stat Streaming SortBy=name

カテゴリ、 Update Streaming Data に負荷が含まれます。

パフォーマンス

4.15 でテクスチャ ストリーマーに改善が加えられましたが、以下はその内容です。どのように改善されたかについて一部の具体的なメトリクスとその目標としたものについて説明します。

テクスチャ ストリーマーが扱うテクスチャ数を減らす

コンポーネント毎に可視性を処理することで改善しました。不可視の隠れたコンポーネントが使用するテクスチャはプリフェッチとしてひとつ低いミップでストリーミングされます。マテリアル毎のテクスチャ ストリーミング データの 追加も、詳細なマップなどの UV チャンネルに適用するスケールを正確に計算して行います。

最後に、静的ジオメトリの (より小さな) マテリアル毎の境界を計算することでも改善が加えられました。

以下のメトリクスは、 Paragon でレベルの 3 種類のビューポイントを使ったものです。

必要なテクスチャ プール

可視の量

スタートアップ

678 MB

564 MB

370 MB

マップのサイド レーン

796 MB

597 MB

308 MB

マップのミドル レーン

1086 MB

674 MB

271 MB

可視テクスチャをストリームインする時間を短縮する

可視テクスチャをストリームインする時間を短縮するために (グローバル テクスチャの割り当てを減らす以外に)、ストリーマーは割り当てられたミップに対する可視ミップのテーブルを維持します。 割り当てられているものから可視ミップを追跡することで、ストリーマーはプリフェッチと強制ロードのデータのストリームイン前に、知覚可能なデータをストリームインすることができます。

以下のメトリクスは、 Paragon でレベルの 3 種類のビューポイントを使ったものです。

可視 MIP のロード

スタートアップ

20s

10s

マップのサイドレーン

19s

9s

マップのミドル レーン

20s

6s

ストリーマーが使う CPU 時間を短縮する

CPU 時間は、動的コンポーネントの処理を非同期のテクスチャ ストリーミング タスクに移動することで改善しました。割り当てを超える状況の処理や、テクスチャのロード順の決定なども 移動しました。

以下の例では、Paragon の最悪の更新フレームの改善を示しています。

ゲームスレッドの更新負荷

最悪の更新フレーム

1.1 ms

0.6 ms

このエリアの他の重要な改善点として、レベルロード時に新規にロードし、まだ可視ではないレベル ストリーミング データのインクリメンタルな処理があります。

ゲーム スレッドをレベルにロードした負荷

インクリメンタルな更新

150 ms

3 ms

低クオリティと不適切な挙動を排除する

メッシュの UV 密度がメッシュ単位ではなくマテリアル単位で計算されるようになりました。この新しいデータは LOD (Level of Detail) も考慮しています。これはテクスチャが低解像度で表示される ほとんどの問題を解決しました。

さらにコンポーネントからパーティクル システムやインスタンス化したメッシュを含む幅広いテクスチャ ストリーミングをサポートするようになりました。これは他の低解像度の問題を解決し 一部のメモリ消費が多い問題も解決しました。

様々なメモリ割り当ての手動調整をなくす

テクスチャ ストリーマーは手動調整なしに様々なメモリ割り当てに自動的に適合することができます。ストリーマーは様々なヒューリスティックを使ってビジュアル面への影響を最小限に抑えながらどのテクスチャを 減らす必要があるかを選択します。

最も少ない量のテクスチャだけが影響を受けるようにし、影響を局所的にします。様々な位置に同じような影響を及ぼさないようにします。

Unreal Engine のドキュメントを改善するために協力をお願いします!どのような改善を望んでいるかご意見をお聞かせください。
調査に参加する
キャンセル