大きなアレイでカーネルを実行しています。clEnqueueNDRange コマンドをプロファイリングすると、実行時間 (終了-開始) は 0.001 ミリ秒ですが、送信から開始 (開始-送信) までの時間は約 120 ミリ秒で、入力データのサイズによって異なります。コマンドが送信されると、実行が開始されるまで何が起こるか。この長い時間を取得することは合理的ですか?
1 に答える
OpenCL は非同期で動作します。つまり、ある仕事を依頼しても、その時点では実現しない場合があるということです。それは将来のある時点で起こります。これは、特にプロファイリングを開始するときは少し奇妙ですが、CPU が OpenGL デバイスの多くの作業をキューに入れ、作業が完了している間に別のことを行うことができるように、このように機能します。
例えば:
clEnqueueWriteBuffer(blah);
clEnqueueNDRange(blah);
clEnqueueReadBuffer(blah, but blocking_read = CL_TRUE);
ここで、writeBuffer と NDRange にかかる時間は非常に短いように見えます。彼らがすることは、何をする必要があるかを記録することだけです。ブロッキング readBuffer は、読み取りの結果を待たなければならないため、時間がかかります。その読み取りが完了するには、読み取りが開始される前に、書き込みとカーネルの実行が完了する必要があります。
現在、読み取りは非常に小さいかもしれませんが、すべてが完了するのを待っているため、かかる時間はその前のコマンドの作業量に依存します。
あなたの質問から何を測定しているのかよくわかりませんが、あなたが見ているのはこの効果だと思います。前の作業が完了するのを待たなければならないため、作業の時間が他の機能に請求されています。
どの関数が CPU を GPU で待機させるかを知ることは、ハイ パフォーマンス コードを作成する際の大きなコツの 1 つです。このような待機を導入すると、CPU は有用な作業を停止し、CPU が次の作業の塊を準備している間、GPU がアイドル状態になる可能性があります。場合によっては、他に選択肢がなく、ただ待つ必要があります。