正常に動作しているアプリに奇妙な問題がありますが、不当なパフォーマンスが失われています。アプリとコードは非公開ですが、ここで詳細な動作モードを示すことができます (かなり単純化されています)。
私のアプリは 4 つのカーネルを使用します。
1. Preprocesses
Reads "I" buffer; Writes to "T" buffer
2. Process
Reads + Writes "T" buffer
3. Parse & Preprocess
Reads + Writes "T" buffer, & writes "O" buffer
4. Check
Reads "O" buffer; Writes to "C" buffer (result of Check)
すべてのバッファがデバイスに保存されます。「I」および「O」バッファは、それぞれ 200kB のバッファです。「T」バッファは約 20MB で、GPU の外部では使用されません。「C」バッファは、結果を示す 4 バイトの int です。
システムは 3 つの異なる形式で実行されます。
- Pure iterative: Write,1,2,3,2,3,2,3,.....,2,3,Read
- Iterative + Reading intermediate: Write,1,2,3,Read,2,3,Read,2,3,.....,2,3,Read
- Iterative + Check: Write,1,2,3,4,Read(C),2,3,4,Read(C),2,3,.....,2,3,Read
最初のモードでは、すべてのカーネルが一度にキューに入れられます。私はそのモードに問題はなく、最大 GPU 使用率 (および CPU) で実行するだけです。他の 2 つのモードでは、カーネルのプログレッシブ キューイングが使用されます。読み取り値が正しくない場合、新しいカーネル セットがキューに入れられます。
ただし、2 番目と 3 番目のモードでは、デバイスからの各読み取りの後、デバイスはしばらくの間アイドル状態のままになります。プログラムのプロファイルを作成しましたが、読み取りごとに GPU が使用されていない時間の小さなギャップ (100us) があります。これは、書き込み部分の後では発生しません。並列化を有効にするために、I/O と実行用に 2 つの個別のキューを作成しましたが、うまくいきませんでした。
ギャップは次のようなものです (ビジュアル プロファイラーの画面を明日投稿できます)。
- 書き込み、1、2、3、読み取り、2、ギャップ、3、読み取り、2、ギャップ、3、.....、2、3、読み取り
この問題は、私がテストした限り、HD5770、HD5570、GTX570、C2050、C2070 で発生します。そしてWindowsとLinuxで。しかし、Quadro 2000M では、並列カーネル実行と I/O を行っても、まったく問題なく動作します!!
私が見逃しているものはありますか?固定されたメモリは、手動の clCreate + clWrite/Read よりも高速ですか? この問題を解決できますか?そのギャップで何度でもカーネル 2 を実行できることに気付きましたが、カーネル 3 を実行することはできません。メモリ「O」は何らかの方法で保護されており、カーネル 3 の実行をブロックしていますか??
PD: モードにギャップのある clWaitForEvents がいくつかあります。それらを削除してテストしたところ、ギャップは約 50% 減少しましたが、CPU 使用率は 20% から 100% に増加しました。これは、CPU、またはスケジューラー/ドライバーと関係があるのでしょうか?