0

Mali 600 gpu の OpenCL ガイドに基づいて、CL_MEM_ALLOC_HOST_PTR を使用してデータ コピーを削除し、パフォーマンスを向上させる必要があります。

今日、Mali 604 GPU を搭載した Arndale ボードで CL_MEM_ALLOC_HOST_PTR を使用してメモリ コピー時間をテストしていました。CL_MEM_ALLOC_HOST_PTR と clEnqueueWriteBuffer でテストしました。CL_MEM_ALLOC_HOST_PTR を使用すると、全体的にパフォーマンスがあまり向上しないことがわかりました。clEnqueueMap 関数は clEnqueueWriteBuffer とほぼ同じ時間がかかるためです。このテストは、ベクトルの追加で行われました。

テスト方法: malloc でポインターを作成してデバイスにデータを転送する代わりに、最初に CL_MEM_ALLOC_HOST_PTR を使用してバッファーを作成しました。次に、OpenCL API を使用してこのバッファーをマップしました。これはポインタを返し、このポインタが指すメモリをデータで埋めました。この場合のマッピング メカニズムには時間がかかります。マッピング時間は clENqueuewritebuffer とほぼ同じです。したがって、この例から、CL_MEM_ALLOC_HOST_PTR を使用しても大きな改善は得られませんでした。

私の質問は、CL_MEM_ALLOC_HOST_PTR を使用すると、マッピング時間がなぜそれほど長くなるのかということです。

パフォーマンス測定値は次のとおりです: 要素サイズ: 10000000、カーネル: ベクトル加算、すべての時間はマイクロ秒単位です

通常の読み取り書き込みバッファ時間 バッファ作成時間 20 エンキュー書き込みバッファ時間 108019

CL_MEM_ALLOC_HOST_PTR - 割り当てられたバッファー内で直接データをコピーする時間 clEnqueueMap によって返されたポインターをデータで満たす 208009 マッピング時間 81346 アンマッピング時間 269

CL_MEM_ALLOC_HOST_PTR-memcpy を使用した malloc ポインターからホスト alloc ポインターへのデータ コピー
あり

Host_alloc_ptr に使用したコード スニペットは次のとおりです。

start = getTime();
    a_st=getTime();
    bufferA = clCreateBuffer(context,  CL_MEM_ALLOC_HOST_PTR, sizeof(cl_float) * ELE_NUM, NULL, &err);
    cl_float* src_a=(cl_float*)clEnqueueMapBuffer(commandQueue, bufferA,CL_TRUE,CL_MAP_WRITE, 0, sizeof(cl_float) * ELE_NUM, 0, NULL, NULL, &err);

    bufferB = clCreateBuffer(context, CL_MEM_ALLOC_HOST_PTR, sizeof(cl_float) * ELE_NUM, NULL, &err);
    cl_float* src_b=(cl_float*)clEnqueueMapBuffer(commandQueue, bufferB,CL_TRUE,CL_MAP_WRITE, 0, sizeof(cl_float) * ELE_NUM, 0, NULL, NULL, &err);
    clFinish(commandQueue);
    a_en=getTime();
    a_time=a_time+(a_en-a_st);

    pfill_s=getTime();
    for (int i = 0; i < ELE_NUM; i++){
        src_a[i] = 100.0;
        src_b[i] = 11.1;

    }
    pfill_e=getTime();
    pfill_time=pfill_time+(pfill_e-pfill_s);

    b_st=getTime();
    clEnqueueUnmapMemObject(commandQueue, bufferB, src_b, 0, NULL, NULL);
    clEnqueueUnmapMemObject(commandQueue, bufferA, src_a, 0, NULL, NULL);
    clFinish(commandQueue);
    b_en=getTime();
    b_time=b_time+(b_en-b_st);


    end = getTime();
    creat_buffer += (end-start);
    bufferC = clCreateBuffer(context, CL_MEM_ALLOC_HOST_PTR, sizeof(cl_float) * ELE_NUM, NULL, &err);
4

1 に答える 1