1

OpenCL で CPU と GPU を同時に利用できるアプリケーションを開発しようとしています。具体的には、CPU 実行用と GPU 用の 2 つのカーネルがあります。CPU カーネルは 1 つのバッファーの内容を変更し、CPU によってバッファーが変更されたことを GPU が検出すると、GPU は他のことを行います。

__kernel void cpuKernel(__global uint * dst1,const uint size)
{
    uint tid  = get_global_id(0);
    uint size = get_global_size(0);

    while(tid < size)
    {
        atomic_xchg(&dst1[tid],10);

        tid += size;
    }
}

__kernel void gpuKernel(__global uint * dst1, __global uint * dst2, const uint size)
{
    uint tid = get_global_id(0);
    uint size = get_global_size(0);

    while(tid < vectorSize)
    {
        while(dst1[vectorOffset + tid] != 10)
            ;

        dst2[vectorOffset + tid] = dst1[vectorOffset+tid];
        tid += size;
    }
}

上記のように、cpuKernel は dst1 バッファーの各要素を 10 に変更し、GPU がそのような変更を検出した後、要素値 (10) を別のバッファー dst2 の同じ場所に割り当てます。cpuKernel は CPU デバイスに関連付けられた command1 にキューされ、gpuKernel は GPU デバイスに関連付けられた command2 にキューされ、2 つのコマンド キューが CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE フラグに設定されています。次に、2 つのケースを作成します。ケース 1:

clEnqueueNDRangeKernel(command2,gpuKernel);
clEnqueueNDRangeKernel(command1,cpuKernel);
clfinish(command1);
clfinish(command2);

ケース 2:

clEnqueueNDRangeKernel(command1,cpuKernel);
clfinish(command1);
clEnqueueNDRangeKernel(command2,gpuKernel);
clfinish(command2);

しかし、結果は、2 つのケースで費やされた時間はほぼ同じであることを示しています。誰でも私を助けることができますか?ありがとう!

または、OpenCL で 2 つのデバイスで非同期に実行される 2 つのカーネルを実装する方法を説明できる人はいますか?

4

1 に答える 1

0

あなたはあまりにも多くを求めています。お気づきかもしれませんが、バッファ オブジェクトはコンテキストに関連していますが、コマンド キューはデバイスに関連しています。カーネルがバッファ オブジェクトで動作する場合、対応するデータはこのデバイス上にある必要があります。clEnqueueWriteBuffer() で明示的に転送しない場合、OpenCL が転送します。

したがって、あるデバイス (CPU など) でカーネルを使用してバッファー オブジェクトを変更し、その直後に別のデバイス (GPU など) で変更すると、OpenCL ドライバーは最初のカーネルが終了するまで待機し、データを転送します。次に、2 番目のカーネルを実行します。

于 2012-10-17T08:09:03.280 に答える