在OpenCL中处理大量常量全局内存

时间:2012-09-21 11:49:19

标签: opencl

我开始在OpenCL中进行一些开发,我的第一个目标之一就是将包含大量数据的库移植到OpenCL。

这个特殊的库包含大量(内存大约20MB)的本机C形式的数组数组,其值严格不变,以及一些允许用户提取的函数(有时执行一些来自这些数组的值的基本操作。

我将所有这些数组放在一个巨大的C源代码文件(大约1M行)中,我将这些代码与函数代码一起编译到库中。

我现在的问题是:是否有可能使用必要的内存限定符将这个巨大的文件编译到使用数据集和相关函数的OpenCL内核中? 同样,这些数组是常量,在执行期间不会更改。

提前感谢所有建议!

汤姆

1 个答案:

答案 0 :(得分:2)

OpenCL支持constant memory,这正是您所需要的。它的工作方式类似于全局内存,但确切的位置可能因实现而异,并且它允许编译器以不同的方式优化,因为内存在内核执行期间不会被修改。

您将创建此缓冲区,将其标记为只读并从主机可访问数据进行复制。然后你通常将它传递给内核:

float[] hugeData = { ... };

void run_kernel() {
   // ...
   cl_mem cl_hugeData;
   hugeDataInOpenCL = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(hugeData), hugeData, &error);
   // ...
   clSetKernelArg(kernel, 0, sizeof(cl_hugeData), &cl_hugeData);
   // ...
}

__kernel void mykernel (__constant float * hugeData, ...) {
   // use hugeData however you want
}

据推测,您可能希望每个上下文创建一次缓冲区并重新使用它(就像使用内核一样)以避免过多的重新工作。

此外,您的数据足够大,以至于某些设备可能没有足够的常量可用内存,在这种情况下,您可以回退到使用全局内存并将其标记为只读。 (这意味着你的内核有两个版本,一个版本带有任何一种参数。)检查clGetDeviceInfo CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE并在运行时决定。