次の方法で共有


居住

オブジェクトは、GPU からアクセス 常駐と見なされます。

常駐予算

GPU はまだページ フォールトをサポートしていないため、GPU がアクセスできる間、アプリケーションはデータを物理メモリにコミットする必要があります。 このプロセスは"常駐するものを作成する" と呼ばれ、物理システム メモリと物理ディスクリート ビデオ メモリの両方に対して実行する必要があります。 D3D12 では、ほとんどの API オブジェクトは GPU アクセス可能なメモリの量をカプセル化します。 その GPU アクセス可能なメモリは、API オブジェクトの作成時に常駐し、API オブジェクトの破棄時に削除されます。

プロセスで使用できる物理メモリの量は、ビデオ メモリの予算と呼ばれます。 バックグラウンド プロセスのウェイクアップとスリープが行われると、予算が著しく変動する可能性があります。ユーザーが別のアプリケーションに切り替わると、大幅に変動します。 予算が変更されたときにアプリケーションに通知し、現在の予算と現在消費されているメモリ量の両方をポーリングできます。 アプリケーションが予算内に留まらない場合、プロセスは断続的に凍結され、他のアプリケーションの実行が許可されるか、作成 API によってエラーが返されます。 IDXGIAdapter3 インターフェイスは、この機能に関連するメソッドを提供します。特に、QueryVideoMemoryInfo と RegisterVideoMemoryBudgetChangeNotificationEventします。

アプリケーションでは、予約を使用して、使用できないメモリの量を示すことが推奨されます。 理想的には、ユーザー指定の "低" グラフィックス設定、またはさらに低いものが、このような予約に適した値です。 予約を設定しても、通常よりも高い予算がアプリケーションに与えられることはありません。 代わりに、予約情報は、OS カーネルが大きなメモリ不足の状況の影響をすばやく最小限に抑えるのに役立ちます。 アプリケーションがフォアグラウンド アプリケーションでない場合でも、予約がアプリケーションで使用できる保証はありません。

ヒープ リソース

多くの API オブジェクトは GPU アクセス可能なメモリをカプセル化しますが、リソース & ヒープは、アプリケーションが物理メモリを消費および管理する最も重要な方法であると予想されます。 ヒープは、物理メモリを管理するための最下位レベルの単位であるため、常駐プロパティに関する知識を持つことは良いことです。

  • ヒープを部分的に常駐させることはできませんが、予約済みリソースには回避策が存在します。
  • ヒープは、特定のプールの一部として予算化する必要があります。 UMA アダプターには 1 つのプールがあり、個別のアダプターには 2 つのプールがあります。 カーネルがディスクリートアダプター上のヒープをビデオメモリからシステムメモリにシフトできることは事実ですが、最後の極端な手段としてのみ行われます。 アプリケーションはカーネルの予算超過の動作に依存せず、代わりに適切な予算管理に集中する必要があります。
  • ヒープは常駐から削除できます。これにより、そのコンテンツをディスクにページングできます。 ただし、ヒープの破棄は、すべてのアダプター アーキテクチャにわたって常駐を解放するためのより信頼性の高い手法です。 D3D12_FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORT のMaxGPUVirtualAddressBitsPerProcess フィールド が予算サイズに近いアダプターでは、削除が確実に常駐を回収
  • ヒープの作成が遅くなる可能性があります。ただし、バックグラウンド スレッド処理用に最適化されています。 レンダリング スレッドのグリッチを回避するために、バックグラウンド スレッドにヒープを作成することをお勧めします。 D3D12 では、複数のスレッドが create ルーチンを同時に安全に呼び出す場合があります。

D3D12 では、アプリケーションのオプションを増やすために、リソース モデルの柔軟性と直交性が向上します。 D3D12 には、コミット済み、配置済み、予約済みの 3 種類のリソースがあります。

  • コミットされたリソースは、リソースとヒープの両方を同時に作成します。 ヒープは暗黙的であり、直接アクセスすることはできません。 ヒープは、ヒープ内のリソース全体を見つけるために適切なサイズに設定されます。
  • 配置されたリソースを使用すると、ヒープ内の 0 以外のオフセットにリソースを配置できます。 オフセットは通常、64 KB に揃える必要があります。ただし、一部の例外は両方向に存在します。 MSAA リソースには 4 MB のオフセットアライメントが必要であり、小さなテクスチャでは 4KB オフセットアライメントを使用できます。 配置されたリソースを別のヒープに直接再配置または再マップすることはできません。ただし、ヒープ間でのリソース データの単純な再配置が可能になります。 新しく配置されたリソースを別のヒープに作成し、リソース データをコピーした後、新しいリソース 記述子を新しいリソース データの場所に使用する必要があります。
  • 予約済みリソースは、アダプターがタイル リソース層 1 以上をサポートしている場合にのみ使用できます。 利用可能な場合は、利用可能な最も高度な常駐管理手法を提供します。ただし、現在、すべてのアダプターでサポートされているわけではありません。 リソース記述子の再生成、部分ミップ レベルの常駐、スパース テクスチャ シナリオなどを必要とせずに、リソースの再マップを有効にします。予約済みリソースが使用可能な場合でも、すべてのリソースの種類がサポートされるわけではないため、完全に一般的なページ ベースの常駐マネージャーはまだ実現できません。

常駐の優先順位

Windows 10 Creators Update を使用すると、メモリ不足でリソースの一部を降格する必要がある場合に、どのヒープとリソースを常駐状態に維持するかを開発者が影響を受けられます。 これにより、開発者は、ランタイムが API の使用から推論できない知識を活用して、パフォーマンスの高いアプリケーションを作成できます。 開発者は、コミットされたリソースの使用からリソースの再取得とタイル化に移行するにつれて、優先順位をより快適に指定できるようになることが期待されます。

これらの優先順位を適用する方が、2 つの動的メモリ予算を管理するよりも簡単で、リソースを手動で降格して昇格させるよりも簡単である必要があります。これは、アプリケーションで既に実行できるためです。 したがって、常駐優先度 API の設計は、作成された各ヒープまたはリソースに割り当てられた適切な既定の優先順位を使用して、コース的に粒度が設定されます。 詳細については、「ID3D12Device1::SetResidencyPriorityD3D12_RESIDENCY_PRIORITY 列挙型」を参照してください。

優先順位により、開発者は次のいずれかを行う必要があります。

  • これらのヒープが自然なアクセス パターンで要求されるよりも早く、またはより頻繁に降格されることによるパフォーマンスへの影響を軽減するために、いくつかの例外的なヒープの優先順位を上げます。 このアプローチは、Direct3D 11 や OpenGL などのグラフィックス API から移植されたアプリケーションによって活用されることが期待されます。リソース管理モデルは Direct3D 12 とは大きく異なります。
  • アクセス頻度または動的に関するプログラマの知識に基づいて、ほぼすべてのヒープ優先順位をアプリケーション独自のバケット化スキームでオーバーライドします。固定スキームは動的なスキームよりも管理が簡単ですが、効果が低く、開発の過程で使用パターンが変化するにつれてプログラマの予防が必要になる可能性があります。 このアプローチは、常駐ライブラリ (特に動的スキーム) を使用するアプリケーションなど、Direct3D 12 スタイルのリソース管理を念頭に置いて構築されたアプリケーションによって活用されることが期待されます。

既定の優先度アルゴリズム

アプリケーションでは、既定の優先度アルゴリズムを最初に過大に設定せずに、管理を試みるヒープに対して有用な優先順位を指定することはできません。 これは、ヒープに特定の優先順位を割り当てる値が、同じメモリを競合する他の優先順位付きヒープに対する相対的な優先順位から派生するためです。

既定の優先順位を生成するために選択される戦略は、ヒープを 2 つのバケットに分類することです。ヒープは、そうでないヒープよりも GPU によって頻繁に書き込まれると見なされるヒープを優先します (優先順位が高くなります)。

優先度の高いバケットには、レンダー ターゲット、深度ステンシル バッファー、または順序指定されていないアクセス ビュー (UAV) として識別するフラグを使用して作成されたヒープとリソースが含まれています。 これらは、D3D12_RESIDENCY_PRIORITY_HIGHから始まる範囲内の優先度値が割り当てられます。これらのヒープとリソースの中でさらに優先順位を付けるために、優先度の最も低い 16 ビットは、ヒープまたはリソースのサイズを 10 MB で割った値に設定されます (非常に大きなヒープの場合は0xFFFF飽和)。 この追加の優先順位付けにより、より大きなヒープとリソースが優先されます。

優先順位の低いバケットには、他のすべてのヒープとリソースが含まれており、D3D12_RESIDENCY_PRIORITY_NORMALの優先順位の値が割り当てられます。 これらのヒープとリソースの間でそれ以上の優先順位付けは試行されません。

プログラミング常駐管理

単純なアプリケーションは、メモリ不足エラーが発生するまでコミットされたリソースを作成するだけで取得できる場合があります。 障害が発生した場合、アプリケーションは他のコミット済みリソースまたは API オブジェクトを破棄して、リソースの作成をさらに成功させることができます。 ただし、単純なアプリケーションであっても、予算の負の変化を監視し、フレームにほぼ 1 回、未使用の API オブジェクトを破棄することを強くお勧めします。

アダプター アーキテクチャの最適化や常駐の優先順位の組み込み時には、常駐管理設計の複雑さが増します。 個別のメモリの 2 つのプールを個別に予算化して管理する方が、1 つだけを管理するよりも複雑になります。また、使用パターンが進化すると、大規模に固定の優先順位を割り当てることが保守上の負担になる可能性があります。 システム メモリ内の間違ったリソースがフレーム レートに深刻な影響を与える可能性があり、テクスチャをシステム メモリにオーバーフローすると複雑さが増します。 また、より高い GPU 帯域幅の恩恵を受けるリソースや、より低い GPU 帯域幅を許容するリソースを特定するのに役立つ簡単な機能はありません。

さらに複雑な設計では、現在のアダプターの機能を照会します。 この情報は、D3D12_FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORTD3D12_FEATURE_DATA_ARCHITECTURED3D12_TILED_RESOURCES_TIER、および D3D12_RESOURCE_HEAP_TIERで使用できます。

アプリケーションの複数の部分は、異なる手法を使用して巻き上がる可能性があります。 たとえば、一部の大きなテクスチャやほとんど実行されないコード パスではコミットされたリソースが使用される場合がありますが、多くのテクスチャはストリーミング プロパティで指定され、一般的な配置されたリソース手法を使用する場合があります。

ID3D12Heap

メモリ管理