このセクションでは、タイムスタンプのクエリと、GPU と CPU のタイムスタンプ カウンターの調整について説明します。
Tip
対話型 GPU プロファイリングとフレーム タイミング分析の場合は、Windowsに PIX を使用します。 PIX には、CPU と GPU の作業を視覚的に関連付ける GPU キャプチャ、タイミング キャプチャ、およびシステム モニター ビューが用意されているため、カスタム タイムスタンプ クエリ インフラストラクチャを記述する前の推奨される開始点となります。 DirectX 12 Agility SDK を使用すると、OS のバージョンに関係なく、プロファイリングと診断に使用できる最新のランタイム機能を使用できます。
タイムスタンプの頻度
アプリケーションでは、コマンド キューごとに GPU タイムスタンプの頻度を照会できます ( ID3D12CommandQueue::GetTimestampFrequency メソッドを参照してください)。
返される周波数は Hz (ティック/秒) で測定されます。 指定したコマンド キューでタイムスタンプがサポートされていない場合 ( 「クエリ」 セクションの表を参照)、この API は失敗し、 E_FAILを返します。 D3D12_COMMAND_LIST_TYPE_DIRECT と D3D12_COMMAND_LIST_TYPE_COMPUTE は常にタイムスタンプをサポートします。 D3D12_COMMAND_LIST_TYPE_COPY は、D3D12_FEATURE_DATA_D3D12_OPTIONS3::CopyQueueTimestampQueriesSupported メンバーが TRUE の場合、タイムスタンプ クエリをサポートすることがあります。
タイムスタンプの調整
D3D12 を使用すると、アプリケーションはタイムスタンプ クエリから取得した結果を、 QueryPerformanceCounterの呼び出しから取得した結果と関連付けることができます。 これは、呼び出し ID3D12CommandQueue::GetClockCalibration によって有効になります。
タイムスタンプは、GPU が上記のすべてのワークロードで終了した時点で GPU によってサンプリングされます。 これは、Direct3D 11 で採用されているのと同じ動作です (GitHubの Direct3D 11.3 機能仕様のD3D11_QUERY_TIMESTAMPを参照)。 つまり、タイムスタンプ クエリは Direct3D 12 ではパイプライン終端のオペレーション (BOP) であることを意味します。
GetClockCalibration は、特定のコマンド キューの GPU タイムスタンプ カウンターをサンプリングし、ほぼ同時に QueryPerformanceCounter を介して CPU カウンターをサンプリングします。 この場合も、指定されたコマンド キューがタイムスタンプをサポートしていない場合、この API は失敗し、E_FAIL が返されます(Queries トピックの表を参照してください)。
GPU および CPU タイムスタンプ カウンターは、必ずしもこれらのプロセッサのクロック速度に直接関連しているわけではありませんが、代わりにタイムスタンプ ティックから機能します。
Warning
一部のハードウェアでは、GPUがアイドル状態のときにGPUタイムスタンプクロックの進行が停止することがあるため、相関がずれる可能性があります。 これを回避するには、開発中に ID3D12Device::SetStablePowerState を呼び出します (開発者モードが有効になっている必要があります)。
タイムスタンプクエリ
タイムスタンプ クエリを使用して、(コマンド キューでの CPU 側の呼び出しではなく) コマンド リストの一部としてタイムスタンプを取得できます。 (一般的な クエリ の詳細については、クエリを参照してください)。
すべてのタイムスタンプ クエリでは、実際のクエリ にD3D12_QUERY_TYPE_TIMESTAMP 型が使用されます。 ただし、ハードウェアの制限により、 D3D12_COMMAND_LIST_TYPE_DIRECT と D3D12_COMMAND_LIST_TYPE_COMPUTE は、D3D12_COMMAND_LIST_TYPE_COPYが使用するD3D12_QUERY_HEAP_TYPE とは異 なる D3D12_QUERY_HEAP_TYPE を使用します。
ダイレクト キューとコンピューティング キューでは 、D3D12_QUERY_HEAP_TYPE_TIMESTAMPが使用されます。
コピー キューは D3D12_QUERY_HEAP_TYPE_COPY_QUEUE_TIMESTAMPを使用します。
コピー キュー クエリは、 D3D12_FEATURE_DATA_D3D12_OPTIONS3::CopyQueueTimestampQueriesSupported メンバーが TRUE の場合にのみサポートされます。
ID3D12GraphicsCommandList::ResolveQueryData を使用して解決されると、タイムスタンプ クエリは、ティックを表す UINT64 になります。これは、ID3D12CommandQueue::GetClockCalibration によって返されます。そのため、長さを秒単位で取得するには、キューの頻度で除算する必要があります。
Important
精度を高める場合は、タイムスタンプの 2 番目またはミリ秒の間隔を計算するときに浮動小数点演算を使用します。 たとえば、queriedTicks / (double)Frequency の代わりに queriedTicks / Frequency を使用します。