OpenCL将数组传递给同一内核的多个实例

时间:2017-01-26 13:03:01

标签: arrays kernel opencl gpu

我有一个内核,我想每次都运行不同的数组输入的多个实例。内核有2个数组输入,我将其称为A和B,我想改变B.

经过大量阅读后,我发现最好的方法是创建多个队列并在每个队列中运行内核的每个实例。所以,如果我有5个不同的数组输入,我需要创建5个队列。以下是我的代码的粗略示例:

// Create memory buffer on device for A and B
cl_mem a_mem_obj = clCreateBuffer(context, CL_MEM_READ_ONLY,...);
cl_mem b_mem_obj[5];

for(int i = 0; i < 5; ++i)
    b_mem_obj[i] = clCreateBuffer(context, CL_MEM_READ_ONLY,...);

// Copy the list A to to memory buffers
for(int i = 0; i < 5; ++i)
    clEnqueueWriteBuffer(queue[i], A, ...);

//Set kernel arguments here

for(int i = 0; i < 5; ++i)
{
    clEnqueueWriteBuffer(queue[i], B[i], ...);
    clSetKernelArgr(kernel, 1, sizeof(cl_mem), b_mem_obj[i]);
    clEnqueueNDRangeKernel(queue[i], kernel, ...);
    clEnqueueReadBuffer(queue[i], output, ...);
}    

for (int i = 0; i < conv1_filters ; i ++) {
    clFlush(queue[i]);
    clFinish(queue[i]);
}

以上适用于小矩阵,但只要我超过100,我就会出现分段错误错误。有什么建议?我顺便使用一个gpu设备。谢谢!

1 个答案:

答案 0 :(得分:1)

clSetKernelArgr(kernel, 1, sizeof(cl_mem), b_mem_obj[i]);
由于没有队列参数,

不会排队。它立即发生并使先前的参数集无效。所以要么你需要从相同的内核字符串编译N个内核,要么你需要分配所有的参数,但只需要在每个队列中只使用必要的一些(比如将队列号作为参数传递,所以在内核中它知道要使用哪个参数数组)

使用许多参数可能会降低执行速度并限制为较小的值。使用来自相同字符串的许多内核可能不会减慢执行速度,但应该受到更大值的限制。

ALL:

clSetKernelArgr(kernel, i, sizeof(cl_mem), b_mem_obj[i]);
each memobj different index so no conflict, pick one in kernel using queue index
kernel string grows 100 times, bad

多个内核:

clSetKernelArgr(kernel[i], 1, sizeof(cl_mem), b_mem_obj[i]);
so it should be clean to read in kernel code
no extra kernel code