0

次のようなデータで実行する必要があるカーネルの長いシーケンスがあります

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仕様にこれに関連する何かがあるかもしれません.

ありがとうございました。

4

2 に答える 2

1

あなたの2番目のケースは行く方法です。

2 番目の (非同期) ケースでは、いくつか質問があります。

Do I have to keep references to all cl_mem objects 
in the long chain of actions and release them after 
everything is complete?

はい。しかし、すべてのデータ配列が同じサイズである場合、2 つだけを使用し、反復ごとに次々に上書きします。次に、2 つのメモリ ゾーンのみが必要になり、解放と割り当ては最初/最後にのみ行う必要があります。

適切なイベントを設定すると、処理は I/O が終了するまで待機します。すなわち:

data -> kernel1 -> data1 -> kernel2 -> data -> kernel3 -> data1
                -> I/O operation    -> I/O operation

これを行うには、最初の I/O が終了した場合にのみ kernel3 を強制的に開始する条件を設定します。そのようにすべてのイベントを連鎖させることができます。

注: I/O 用と処理用の 2 つのキューを使用すると、2 倍高速な並列 I/O が実現します。

重要なのは、すべてのメモリ オブジェクトの合計がデバイスで使用可能なメモリの合計を超えた場合、OpenCL はどのように処理するのでしょうか?

割り当て時に OUT_OF_RESOURCES などのエラーが発生します。

どの時点でも、カーネルは入力カーネルと出力カーネル (メモリに収まる必要があります) のみを必要としますが、これらのバッファの 4 つまたは 5 つが合計を超えた場合、OpenCL はこれらのメモリ オブジェクトを舞台裏でどのように割り当て/割り当て解除しますか? これは読み取りにどのように影響しますか?

メモリをホスト PTR として設定していない限り、これは自動的には行われません。しかし、その方法で OpenCL ドライバーが適切に処理するかどうかはわかりません。私があなただったら、最大数以上は割り当てません。

于 2013-01-16T23:34:35.457 に答える
1

cl_mem 参照を使用してカーネルをキューに入れると、それらのオブジェクトが保持され、カーネルが完了すると、それらを解放します。

これにより、カーネルが実行を完了するのを実際に待つことなく、カーネルをキューに入れた後にこれらのオブジェクトを解放できます。これにより、非同期の "clEnqueue" 操作が同期操作 (つまり、メモリの解放) と調整され、ランタイムとカーネルによる解放されたメモリ オブジェクトの使用が防止されます。

于 2013-01-19T19:37:06.083 に答える