我正在运行下面的OpenCL内核,其二维全局工作大小为1000000 x 100,本地工作大小为1 x 100。
__kernel void myKernel(
const int length,
const int height,
and a bunch of other parameters) {
//declare some local arrays to be shared by all 100 work item in this group
__local float LP [length];
__local float LT [height];
__local int bitErrors = 0;
__local bool failed = false;
//here come my actual computations which utilize the space in LP and LT
}
然而,这拒绝编译,因为在编译时不知道参数length
和height
。但我根本不清楚如何正确地做到这一点。我应该使用memalloc的指针吗?如何以一种方式处理这个问题,即内存只为整个工作组分配一次,而不是每个工作项分配一次?
我需要的只是2个浮点数组,1个int和1个布尔值,它们在整个工作组之间共享(因此所有100个工作项)。但我没有找到任何正确做到这一点的方法......
答案 0 :(得分:24)
相对简单,您可以将本地数组作为参数传递给内核:
kernel void myKernel(const int length, const int height, local float* LP,
local float* LT, a bunch of other parameters)
然后,您设置kernelargument,value
NULL
和size
等于您要为参数分配的大小(以字节为单位)。因此它应该是:
clSetKernelArg(kernel, 2, length * sizeof(cl_float), NULL);
clSetKernelArg(kernel, 2, height* sizeof(cl_float), NULL);
本地内存总是由工作组共享(而不是私有),所以我认为bool
和int
应该没问题,但如果没有,你也可以将它们作为参数传递。< / p>
与你的问题没有关系(并不一定相关,因为我不知道你计划在哪个硬件上运行它),但至少gpus不像工作量那样不是特定的倍数2的力量(我认为nvidia是32,amd是64),这意味着可能会创建128个项目的工作组,其中最后28个基本上是浪费。因此,如果您在gpu上运行opencl,如果直接使用大小为128的工作组(并适当地更改全局工作大小),则可能有助于提高性能
作为旁注:我从未理解为什么每个人都使用kernel, local and global
的下划线变体,对我来说似乎更加丑陋。
答案 1 :(得分:1)
您不必在内核之外分配所有本地内存,尤其是当它是一个简单的变量而不是数组时。
您的代码无法编译的原因是OpenCL不支持本地内存初始化。这在文档(https://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/local.html)中指定。它在CUDA(Is there a way of setting default value for shared memory array?)
中也是不可行的ps:Grizzly的答案已经足够好了,如果我可以将其作为评论发布,那会更好,但我受到声誉政策的限制。遗憾。
答案 2 :(得分:1)
你也可以像这样声明你的数组:
__local float LP[LENGTH];
并将LENGTH作为内核编译中的定义传递。
int lp_size = 128; // this is an example; could be dynamically calculated
char compileArgs[64];
sprintf(compileArgs, "-DLENGTH=%d", lp_size);
clBuildProgram(program, 0, NULL, compileArgs, NULL, NULL);