7

OpenCL1.1仕様は次のように述べています。

cl_int clEnqueueBarrier(cl_command_queue command_queue)

clEnqueueBarrierは、コマンドの次のバッチが実行を開始する前に、command_queue内のキューに入れられたすべてのコマンドの実行が終了することを保証する同期ポイントです。

cl_int clFinish(cl_command_queue command_queue)

command_queueで以前にキューに入れられたすべてのOpenCLコマンドが関連するデバイスに発行され、完了するまでブロックします。clFinishは、command_queue内のキューに入れられたすべてのコマンドが処理されて完了するまで戻りません。clFinishは同期ポイントでもあります。

インオーダーまたはアウトオブオーダーの実行で何かをしなければならないはずですが、違いがわかりません。順番に実行する場合、それらが必要になることはありますか?現時点では、次のようなことをしています。

...
for(...){
    clEnqueuNDRangeKernel(...);
    clFlush(command_queue);
    clFinish(command_queue);
}
...

NvidiaGPUで。関連するコメントをいただければ幸いです。

4

1 に答える 1

6

依存関係を確保する方法の 1 つとして順不同のキューを作成する場合は、バリアをキューに入れる必要があります。cl_eventオブジェクトを使用して、コマンド キューでのコマンドの正しい順序を確認する こともできます。

clFinishカーネル呼び出しのたびにa を呼び出すようにコードを記述している場合、 を使用しclEnqueueBarrierてもコードに影響はありません。これは、既に順序付けが保証されているためです。

を使用するポイントは、次のclEnqueueBarrierような場合です。

clEnqueueNDRangeKernel(queue, kernel1);
clEnqueueBarrier(queue);
clEnqueueNDRangeKernel(queue, kernel2);

この場合、kernel2 は kernel1 の結果に依存します。このキューが順不同である場合、バリアがないと、kernel2kernel1 の前に実行され、不正な動作が発生する可能性があります。次の方法で同じ順序を実現できます。

clEnqueueNDRangeKernel(queue, kernel1);
clFinish(queue);
clEnqueueNDRangeKernel(queue, kernel2);

clFinishキューが空になるまで待機するためです (すべてのカーネル/データ転送が終了します)。ただし、clFinishkernel1 が完了するまで待機します。この場合、whileclEnqueueBarrierはすぐに制御をアプリケーションに戻します (より多くのカーネルをエンキューしたり、他の有用な作業を実行したりできるようにします)。

clFinish補足として、暗黙的に呼び出すと思うclFlushので、毎回呼び出す必要はありません。

于 2012-11-02T18:22:15.433 に答える