次のようなデータで実行する必要があるカーネルの長いシーケンスがあります
data -> kernel1 -> data1 -> kernel2 -> data2 -> kernel3 -> data3 etc.
すべての中間結果もホストにコピーする必要があるため、アイデアは次のようになります (疑似コード):
inputdata = clCreateBuffer(...hostBuffer[0]);
for (int i = 0; i < N; ++i)
{
// create output buffer
outputdata = clCreateBuffer(...);
// run kernel
kernel = clCreateKernel(...);
kernel.setArg(0, inputdata);
kernel.setArg(1, outputdata);
enqueueNDRangeKernel(kernel);
// read intermediate result
enqueueReadBuffer(outputdata, hostBuffer[i]);
// output of operation becomes input of next
inputdata = outputdata;
}
これらの操作をスケジュールするには、いくつかの方法があります。
- 最も簡単なのは、前のエンキュー操作のイベントを常に待機することです。つまり、読み取り操作が完了するのを待ってから、次のカーネルに進みます。必要がなくなったらすぐにバッファーを解放できます。
- または、すべてを可能な限り非同期にします。カーネルと読み取りエンキューは前のカーネルのみを待機するため、別のカーネルの実行中にバッファー読み取りが発生する可能性があります。
2 番目の (非同期) ケースでは、いくつか質問があります。
- アクションの長いチェーンですべての cl_mem オブジェクトへの参照を保持し、すべてが完了したら解放する必要がありますか?
- 重要なのは、すべてのメモリ オブジェクトの合計がデバイスで使用可能なメモリの合計を超えた場合、OpenCL はどのように処理するのでしょうか? どの時点でも、カーネルは入力カーネルと出力カーネル (メモリに収まる必要があります) のみを必要としますが、これらのバッファの 4 つまたは 5 つが合計を超えた場合、OpenCL はこれらのメモリ オブジェクトを舞台裏でどのように割り当て/割り当て解除しますか? これは読み取りにどのように影響しますか?
誰かがこれらの状況で何が起こるかを明確にしてくれるとありがたいです.OpenCL仕様にこれに関連する何かがあるかもしれません.
ありがとうございました。