0

CL_MEM_USE_HOST_PTR と CL_MEM_COPY_HOST_PTR がどのように機能するかを正確に理解しようとしていました。基本的に、CL_MEM_USE_HOST_PTR を使用して 2D 画像を作成する場合、これはデバイスに何もコピーしません。代わりに、GPU がホスト上のマップされたメモリを参照し (clEnqueueMapBuffer がマップします)、処理を実行し、結果を別の場所に書き込むことができます。 .

一方、CL_MEM_COPY_HOST_PTRを使用すると、デバイス上のホストptrが指すデータのコピーが作成されます(キャッシュだけでなく、別のコピーが作成されると思います)。これで、デバイスにコピーされたデータに対して処理が実行され、結果がホストにコピーされます。正しく理解できたと思います。

だから私の質問は... このようにしたいのは私の好奇心からです。CL_MEM_USE_HOST_PTR を使用し、デバイスがホスト メモリにアクセスできるようになったとしても、GPU カーネルがデバイス自体に別のコピーを作成するようにします (これはホスト自体で行われるため、COPY_HOST_PTR は使用しません)。このデータを処理します。これはどのように行うことができますか??

4

3 に答える 3

1

CL_MEM_READ_WRITEを使用してコピーするバッファを作成しますが、ホストで初期化しないでください。最近、連続する整数に新しいバッファを初期化する必要がありました

cl_mem _offsetBuffer;
_offsetBuffer = clCreateBuffer(_context, CL_MEM_READ_WRITE, (size_t)(count * sizeof(cl_int)), NULL, &errorCode);

上記のclCreateBufferは、メモリオブジェクトへのハンドルを提供する以外は、ホストのメモリに対して何もしません。次に、カーネルを使用してシーケンシャル値を割り当てます。これは、グラフィックカードのメモリ速度がCPUに値を割り当てるよりもはるかに高速であることが証明されたためです。

__kernel void initOffsetBuffer(__global int* offsetBuffer, const int offsetBufferLength, const int startValue){
    int gid = get_global_id(0);
    int gs = get_global_size(0);
    int i;
    for(i=gid;i<offsetBufferLength;i+=gs){
        offsetBuffer[i] = i+startValue;
    }
}

この時点では、ホストメモリにバッファのコピーはまだありません。clEnqueueReadBufferを使用してホストにコピーする必要があります。

このコードを簡単に変更して、単なる割り当てではなく、コピーカーネルにすることができます。

__kernel void copyBuffer(__global const int* srcBuffer, __global int* dstBuffer, const int bufferLength){
    int gid = get_global_id(0);
    int gs = get_global_size(0);
    int i;
    for(i=gid;i<bufferLength;i+=gs){
        dstBuffer[i] = srcBuffer[i];
    }
}
于 2012-07-08T16:10:02.110 に答える
1

通常、OpenCL バッファは、ホスト メモリに「ビット」のコピーを持っています (これは、バッファの内容が OpenCL 仕様で呼び出される方法です)。これが必要なのは、デバイスのメモリが限られているためです。ビットは通常、カーネルによって使用される場合にのみデバイスに転送されます。

USE_HOST_PTR を使用してバッファーを作成すると、OpenCL ランタイムがこのホスト メモリ コピーに host_ptr の場所を使用できるようになります。カーネルがバッファを使用すると、ビットがデバイスにコピーされます。実行後、ビットがホスト メモリに同期されていることを確認する必要があります。これは を呼び出すことによって行われclEnqueueMapBuffer、この関数によって返されるポインタはホスト メモリ領域内にあります。

COPY_HOST_PTR を使用してバッファーを作成すると、ランタイムはバッファーの新しいホスト メモリ コピーを割り当て、ビットをコピーします。通常、この時点では何もデバイスに送信されません。

于 2012-07-08T18:18:39.837 に答える
0

CL_MEM_HOST_PTR - 実際には、cl_mem オブジェクトはデバイスにメモリを割り当て、ホスト ポインターによって指定されたデータをコピーします。デバイス側でバッファ オブジェクトを変更しても、ホスト側には表示されません。

CL_MEM_USE_HOST_PTR - cl_mem オブジェクトは、host_ptr によって参照されたメモリを使用するため、デバイスは、データ転送を必要としないこの方法で、ホスト データに割り当てられたデータを直接変更できます。

于 2014-06-17T13:45:24.297 に答える