私はOpenCLでちょっと試してみましたが、ホストとデバイス間のメモリ転送速度をテストしています。 私はIntel OpenCL SDKを使用していて、統合グラフィックスのIntel i5 Processorで動作していました。 私はそのように同様に固定メモリを使用する場合より速くほぼ10倍であることが判明代わりclEnqueueWriteBuffer
のclEnqueueMapBuffer
を発見:a
b
とret
128ビット整列のint配列であるCL_MEM_ALLOC_HOST_PTRはCL_MEM_USE_HOST_PTRよりも遅い
int amt = 16*1024*1024;
...
k_a = clCreateBuffer(context,CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, sizeof(int)*amt, a, NULL);
k_b = clCreateBuffer(context,CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, sizeof(int)*amt, b, NULL);
k_c = clCreateBuffer(context,CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR, sizeof(int)*amt, ret, NULL);
int* map_a = (int*) clEnqueueMapBuffer(c_q, k_a, CL_TRUE, CL_MAP_READ, 0, sizeof(int)*amt, 0, NULL, NULL, &error);
int* map_b = (int*) clEnqueueMapBuffer(c_q, k_b, CL_TRUE, CL_MAP_READ, 0, sizeof(int)*amt, 0, NULL, NULL, &error);
int* map_c = (int*) clEnqueueMapBuffer(c_q, k_c, CL_TRUE, CL_MAP_WRITE, 0, sizeof(int)*amt, 0, NULL, NULL, &error);
clFinish(c_q);
。 時間は、しかしclEnqueueWriteBuffer
を私は91.350065ミリ
に
k_a = clCreateBuffer(context,CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR, sizeof(int)*amt, NULL, NULL);
k_b = clCreateBuffer(context,CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR, sizeof(int)*amt, NULL, NULL);
k_c = clCreateBuffer(context,CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR, sizeof(int)*amt, NULL, NULL);
int* map_a = (int*)clEnqueueMapBuffer(c_q, k_a, CL_TRUE, CL_MAP_READ, 0, sizeof(int)*amt, 0, NULL, NULL, &error);
int* map_b = (int*)clEnqueueMapBuffer(c_q, k_b, CL_TRUE, CL_MAP_READ, 0, sizeof(int)*amt, 0, NULL, NULL, &error);
int* map_c = (int*)clEnqueueMapBuffer(c_q, k_c, CL_TRUE, CL_MAP_WRITE, 0, sizeof(int)*amt, 0, NULL, NULL, &error);
/** initiate map_a and map_b **/
時間の増加に自分のコードを変更したときに、どのような可能性が使用して198.604528 MSに比べ、およそ22.026186ミリに出てきました問題なの?それとも、まったく問題なの?
EDIT: これは、私は2番目のコードで配列を初期化する方法である:
for (int i = 0; i < amt; i++)
{
map_a[i] = i;
map_b[i] = i;
}
そして今、私がチェックしていること、map_aとmap_b がプログラムの最後に右の要素が含まれていますが、ありませんmap_cにはすべて0が含まれます。私はこれでした:
clEnqueueUnmapMemObject(c_q, k_a, map_a, 0, NULL, NULL);
clEnqueueUnmapMemObject(c_q, k_b, map_b, 0, NULL, NULL);
clEnqueueUnmapMemObject(c_q, k_c, map_c, 0, NULL, NULL);
を、私のカーネルは、私の理解では、CL_MEM_ALLOC_HOST_PTRが割り当てるが、コピーされないということであるだけで
__kernel void test(__global int* a, __global int* b, __global int* c)
{
int i = get_global_id(0);
c[i] = a[i] + b[i];
}
2番目のコードでは、a、b、retデータを使ってk_a、k_b、k_cをどのように初期化するか、clFinishはどのように初期化することができますか? 2つのコードが異なることをすると、あなたを助けることは難しいでしょう –
申し訳ありませんが、コードは同じです。私は偶然にすべてをコピーしませんでした。2番目のコードでは、map_cからデータを読み込めると思ったので、k_cをretで初期化しません。 – selena731
マッピングと使用の後で、メモリの一貫性を保証するためにマップされたオブジェクトのマップを解除するか、clWrite/Readを実行する必要があります。 – DarkZeros