JOCL:为什么要使用缓冲区?

时间:2012-01-26 14:49:58

标签: opencl

给定一个float[n] inputdata传递给OpenCL内核,有没有人可以通过以下三种方式将这个传递给内核来区别开发:

A)

cl_mem input = clCreateBuffer(context, CL_MEM_USE_HOST_PTR Sizeof.cl_float * n,
        inputdata, NULL);
clSetKernelArg(kernel, i, Sizeof.cl_mem, Pointer.to(input));

B)

clSetKernelArg(kernel, i, Sizeof.cl_float * n, Pointer.to(inputdata));

C)

cl_mem input = clCreateBuffer(context, CL_MEM_options_here, Sizeof.cl_float * n,
        NULL, NULL);
clEnqueueWriteBuffer(command_queue, input, CL_TRUE, 0, Sizeof.cl_float * n, 
        inputdata, 0, NULL, NULL);
clSetKernelArg(kernel, i, Sizeof.cl_mem, Pointer.to(input));

我是否理解A)和C)之间的区别在于C)在开始时复制整个阵列一次,然后在GPU上工作,而A)必须即时加载其数据?所以如果只需要一小部分数组,A)是好的,如果你使用整个数组,C)是要走的路吗?

那么B)呢?它更像是A),更像是C),还是还有不同的东西?

2 个答案:

答案 0 :(得分:1)

是的,您无法传递大量参数。所有参数的大小都有一个上限(通常在50 KiB范围内 - 您可以使用clGetDeviceInfoCL_DEVICE_MAX_PARAMETER_SIZE进行查询)。使用方法a和c,您可以传递更大的缓冲区(数百兆字节).a对OpenCL 1.1及更低版本没有帮助,因为缓冲区通常仍会被复制,但使用OpenCL 1.2,如果您的主机和设备是相同的(例如,您正在运行CPU OpenCL运行时。)

答案 1 :(得分:0)

每种方法的作用:

A)此方法使用主机的缓冲区来存储数据。当您不想将数据复制到设备,但想要就地使用它时。我相信这只能在CPU设备上实现,但我并不完全确定。

B)将__global *类型传递给您的内核。将此用于有限数量的数据。请注意,对于__local / NULL版本,性能可能会受到大量工作项/组的极大(和消极)影响。大小仅限于CL_DEVICE_MAX_PARAMETER_SIZE。传递NULL将导致__local *类型,限制为CL_DEVICE_LOCAL_MEM_SIZE。

C)当您的内核需要大量(即大于方法B的限制)数据量时使用此选项。这会将主机缓冲区中的数据复制到设备的缓冲区。如果您的数据已准备就绪,可以在创建cl_mem缓冲区时使用mem标志CL_MEM_COPY_HOST_PTR进行复制,并跳过clEnqueueWriteBuffer调用。