帯域幅、CPUの使用率、およびGPUの使用率の両方に非常に集中的にアプリケーションを別のGPUからおよそ10〜15ギガバイト毎秒を転送する必要があります。 DX11 APIを使用してGPUにアクセスしているため、GPUへのアップロードは、1回のアップロードごとにマッピングが必要なバッファでのみ実行できます。アップロードは一度に25MBのチャンクで行われ、16スレッドはマップバッファにバッファを同時に書き込んでいます。これについては何もできません。次のバグがなければ、書き込みの実際の同時実行レベルは低くなければなりません。
3つのPascal GPU、ハイエンドのHaswellプロセッサー、4チャネルRAMを搭載した堅牢なワークステーションです。ハードウェア上の改善はあまりありません。これは、Windowsのデスクトップ版を実行している10
実際の問題
私が合格したら〜50%のCPU負荷、にマップされたメモリにアクセスする際に呼び出されるWindowsカーネル、内部MmPageFault()
で何か(あなたアドレス空間はまだOSによってコミットされていませんでした)はひどく壊れ、残りの50%のCPU負荷はMmPageFault()
のスピンロックで無駄になっています。 CPUが100%活用され、アプリケーションのパフォーマンスが完全に低下します。
これは、毎秒プロセスに割り当てる必要があり、DX11バッファがマップされていないときにプロセスから完全にマップされていない膨大な量のメモリが原因であると考えます。それに対応して、実際にはMmPageFault()
への呼び出しは何千回も起こりますが、これは連続的に発生します。memcpy()
は順次バッファに書き込まれます。遭遇した個々のコミットされていないページ。
CPU負荷が50%を超えると、ページ管理を保護するWindowsカーネルの楽観的なスピンロックによって、パフォーマンスが完全に低下します。
考慮事項
バッファはDX11ドライバにより割り当てられます。割り当て戦略については何も調整できません。異なるメモリAPIの使用、特に再利用は不可能です。
DX11 APIの呼び出し(バッファのマッピング/アンマップ)はすべて1つのスレッドから発生します。実際のコピー操作は、システム内の仮想プロセッサより多くのスレッドでマルチスレッド化される可能性があります。
メモリ帯域幅の要件を減らすことはできません。これはリアルタイムアプリケーションです。実際、ハード制限は現在、プライマリGPUのPCIe 3.0 16x帯域幅です。私ができるならば、私はすでにさらに進める必要があります。
マルチスレッドコピーを避けることはできません。独立したプロデューサ - コンシューマキューがあり、それらは簡単にはマージできません。
スピンロックのパフォーマンスの低下は非常に稀です(ユースケースではそれを押しているため)、Googleではスピンロック機能の名前には1つの結果が見つかりません。
マッピングをより詳細に制御するAPI(Vulkan)へのアップグレードは進行中ですが、短期的な修正には適していません。現在のところ、より良いOSカーネルに切り替えることは、同じ理由からオプションではありません。
CPU負荷を軽減することもできません。 (通常は些細で安価な)バッファコピー以外の作業が必要な作業が多すぎます。
質問
何ができますか?
個々のページフォールトの数を大幅に減らす必要があります。私は自分のプロセスにマップされているバッファのアドレスとサイズを知っており、メモリがまだコミットされていないことも知っています。
最小限のトランザクションでメモリをコミットする方法を教えてください。
アンマップ後のバッファの割り当て解除を防止するDX11のエキゾチックなフラグ、単一のトランザクションでコミットを強制するWindows API、ほとんど何でも歓迎します。
現在の状態
// In the processing threads
{
DX11DeferredContext->Map(..., &buffer)
std::memcpy(buffer, source, size);
DX11DeferredContext->Unmap(...);
}
あなたはすべての16スレッドすべてをまとめて約400Mのように聞こえます。かなり低い。アプリケーションでこれを超えないことを確認できますか?ピックメモリ消費量は何ですか?私はあなたがメモリリークを持っているのだろうかと思います。 – Serge
ピーク消費量は約7-8GBですが、すべての種類のボトルネックを補うためには、処理パイプライン全体が合計で1秒以上のバッファリングを必要とすることを考慮すると、正常です。はい、それは「唯一の」400MB、毎秒25回です。そして、基本的なCPU負荷が50%を超え、スピンロックのパフォーマンスが完全にCPU使用率の0〜40-50%に急上昇するまでうまく動作します。同時にシステム上の他のプロセスにも影響を与えます。 – Ext3h
1.あなたの物理的な記憶は何ですか?他のアクティブなプロセスをすべて終了できますか? 2.あなたが50%のしきい値を見ているので#2を推測すると、ハイパースレッディングに関するいくつかの問題が発生する可能性があります。物理コアの数はいくつですか? 8?ハイパースレッディングを無効にすることはできますか?クリーンなマシン上で実際のCPUと同じ数のスレッドを実行してみてください。 – Serge