コンテキストの監視

この記事では、コンテキストの監視に関する情報を提供します。これにより、GPU エンジン間、または CPU コアと GPU エンジン間での柔軟な同期が可能になります。 監視対象のフェンス オブジェクトは、高度な形式のフェンス同期であり、CPU コアまたは GPU エンジンが特定のフェンス オブジェクトに信号を送ったり、待機したりすることができます。

監視対象フェンスの作成

Direct3D ランタイムは、D3DDDI_MONITORED_FENCE 同期オブジェクト型を使用して、ユーザー モード ドライバーの (UMD) CreateSynchronizationObjectCb を呼び出すことで、監視対象フェンス オブジェクトを作成します。

監視対象フェンス オブジェクトは、次の属性と共に作成されます。

  • 初期値
  • フラグ (待機動作とシグナル通知動作を指定する)

作成すると、グラフィックス カーネルは、次の項目で構成されるフェンス オブジェクトを返します。

アイテム 説明
hSyncObject 同期オブジェクトへのハンドル。 グラフィックス カーネルの呼び出しで参照するために使用されます。
FenceValueCPUVirtualAddress CPU のフェンス値 (64 ビット) の読み取り専用マッピング。 このアドレスは、I/O コヒーレンシーをサポートするプラットフォーム上の CPU の観点から WB (キャッシュ可能) にマップされます。UC (キャッシュされていない) は他のプラットフォーム上にあります。 このメモリ位置を読み取るだけで、CPU がフェンスの進行状況を追跡できるようにします。 CPU は、このメモリ位置への書き込みを許可されていません。 フェンスを通知するには、SignalSynchronizationObjectFromCpuCb を呼び出すために CPU が必要です。 IoMmu をサポートするアダプターは、GPU アクセスにこのアドレスを使用する必要があります。 この場合、アドレスは読み取り/書き込みとしてマップされます。
FenceValueGPUVirtualAddress GPU のフェンス値 (64 ビット) の読み取り/書き込み専用マッピング。 このアドレスは、それをサポートするプラットフォームで I/O コヒーレンシーを必要とするようにマップされます。 フェンスを通知するために、GPU はこの GPU 仮想アドレスに直接書き込みを許可されます。 IoMmu GPU では、このアドレスを使用しないでください。

フェンス値は 64 ビット値で、それぞれの仮想アドレスは 64 ビット境界に配置されます。 GPU は、追加された DXGK_VIDSCHCAPS::No64BitAtomics フラグを使用して、CPU によって表示される 64 ビット値をアトミックに更新できるかどうかを宣言する必要があります。 GPU が 32 ビット値のみをアトミックに更新できる場合、OS はフェンス ラップアラウンド ケースを自動的に処理します。 ただし、未処理の待機と信号のフェンス値を、最後に通知されたフェンス値から UINT_MAX/2 より大きくすることはできないという制限が設けられます。

GPU シグナル

GPU エンジンが仮想アドレスを使用して監視対象のフェンスに書き込めない場合、ユーザー モード ドライバー (UMD) は SignalSynchronizationObjectFromGpuCb コールバックを使用して、ソフトウェア信号パケットを GPU コンテキストにキューします。

GPU からフェンスを通知するために、UMD はカーネル モードを経由せずに直接、フェンス書き込みコマンドをコンテキスト コマンド ストリームに挿入します。 カーネルがフェンスの進行状況を監視するメカニズムは、特定の GPU エンジンが監視対象フェンスの基本実装と高度な実装のどちらをサポートしているかによって異なります。

GPU でコマンド バッファーの実行が完了すると、グラフィックス カーネルは次のようになります。

  • このプロセスに対して通知される可能性のある保留中の待機を含むフェンス オブジェクトの一覧を確認します
  • 現在のフェンス値を読み取ります
  • 待機を待機していない必要があるかどうかを判断します。

GPU 待機

GPU エンジンで監視対象のフェンスを待機するには、まず UMD が保留中のコマンド バッファーをフラッシュしてから、フェンス オブジェクト (hSyncObject) と待機中のフェンス値を指定して WaitForSynchronizationObjectFromGpuCb を呼び出す必要があります。 グラフィックス カーネルは、内部データベースへの依存関係をキューに入れ、UMD に直ちに戻り、待機操作の背後で作業をキューに入れ続けることができます。 待機操作の後に送信されたコマンド バッファーは、待機操作が満たされるまで実行がスケジュールされません。

CPU シグナル

SignalSynchronizationObjectFromCpuCb コールバックが追加され、CPU が監視対象フェンス オブジェクトを通知できるようにしました。 CPU が監視対象のフェンス オブジェクトにシグナルを送信すると、グラフィックス カーネルはフェンスのメモリ位置をシグナル値で更新します。 この値は、任意のユーザー モード リーダーにすぐに表示され、満たされた待機をすぐに解除します。

CPU 待機

監視対象フェンス オブジェクトで CPU が待機できるように、WaitForSynchronizationObjectFromCpuCb コールバックが追加されました。 2 つの形式の待機操作を使用できます。 最初の形式では、WaitForSynchronizationObjectFromCpuCb は待機が満たされるまでブロックします。 2 番目の形式では、WaitForSynchronizationObjectFromCpuCb は、待機状態が満たされると通知される CPU イベントへのハンドルを受け取ります。