给出一个要传递给OpenCL内核的float[n] inputdata,有没有人能告诉我下面三种传递给内核的方法之间的区别:
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),还是还有一些不同的东西?
发布于 2012-01-27 02:45:18
是的,你不能传递大量的参数。所有参数的大小都有一个上限(通常在50 KiB范围内--可以用clGetDeviceInfo和CL_DEVICE_MAX_PARAMETER_SIZE查询)。使用方法a和c,可以传递更大的缓冲区(数百兆字节)。A对于CPU1.1和更低版本没有帮助,因为缓冲区通常仍将被复制,但对于OpenCL 1.2,如果您的主机和设备相同(例如,您正在运行OpenCL OpenCL运行时),则可以避免一次复制。
发布于 2012-01-27 06:00:20
每种方法的作用:
A)此方法使用主机的缓冲区来存储数据。当您不想将数据复制到设备,但想就地使用它时。我相信这只在CPU设备上是可能的,但我不能完全确定。
B)将__global*类型传递给内核。将此选项用于有限数量的数据。请注意,对于__local/NULL版本,性能可能会受到大量工作项/组的极大(和负面)影响。大小限制为CL_DEVICE_MAX_PARAMETER_SIZE。传递NULL会导致__local*类型,限制为CL_DEVICE_LOCAL_MEM_SIZE。
C)当你的内核需要大量的数据时(也就是大于方法B的限制),使用这个函数。这会将数据从主机的缓冲区复制到设备的缓冲区。如果您的数据已准备就绪,则可以在创建cl_mem缓冲区时使用内存标志CL_MEM_COPY_HOST_PTR复制它,并跳过clEnqueueWriteBuffer调用。
https://stackoverflow.com/questions/9019906
复制相似问题