2012-01-17 26 views
11

我正在下面1000000×100二维全球工作的大小和1×100如何在OpenCL中声明本地内存?

__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 
} 

然而,这拒绝编译一个地方工作尺寸的OpenCL内核,因为参数length和编译时不知道height。但我不清楚如何正确地做到这一点。我应该使用指针与memalloc?如何处理这种内存只能为整个工作组分配一次而不是每个工作项一次?

我需要的是在整个工作组之间共享2个浮点数,1个整数和1个布尔值的数组(所有100个工作项目)。但是我无法找到,这是否正确任何方法...

+0

http://stackoverflow.com/questions/2541929/how-do-i-use-local-memory-in-opencl – 2016-03-31 16:25:26

回答

23

它是相对简单的,你可以通过当地的数组作为参数传递给内核:

kernel void myKernel(const int length, const int height, local float* LP, 
        local float* LT, a bunch of other parameters) 

你再设置kernelargument与valueNULLsize等于您想为参数分配的大小(以字节为单位)。因此,它应该是:

clSetKernelArg(kernel, 2, length * sizeof(cl_float), NULL); 
clSetKernelArg(kernel, 2, height* sizeof(cl_float), NULL); 

本地内存总是由工作组(而不是私人)共享的,所以我觉得boolint应该罚款,但如果没有,你可以随时通过这些测试参数太多。

与您的问题并不真正相关(并且不一定相关,因为我不知道您计划运行此硬件的硬件),但至少gpus不特别适用于不是特定功率倍数的工作原理(我认为nvidia是32,amd是64),这意味着这可能会创建128个项目的工作组,其中最后28个基本上被浪费了。所以,如果你在GPU上运行opencl,它可能会帮助你的性能,如果你直接使用128号工作组(并且适当地改变全局工作尺寸)

作为一个方面:我从来不明白为什么每个人都使用下划线变体kernel, local and global,对我来说似乎更加丑陋。

+0

嗯...所以我应该怎么解决这个工作组规模问题?100是标称值,它可以根据问题的确切实例而有所不同,但我需要这些局部内存变量用于全局输入的每个1x100子块。我认为如果该子块不是工作组,则无法在其正确的1x100子块之间共享变量? (至于旁注,我从来没有尝试没有__,感谢提示!) – user1111929 2012-01-17 07:30:48

+0

我应该传递一个二维数组然后传递给内存,但我该怎么做?我可以沿'clSetKernelArg(kernel,2,length * local_work_size [0] * sizeof(cl_float),NULL)'行传递一些东西;'但是这是一个一维数组。它可能会更好,使其2维,或不? – user1111929 2012-01-17 07:41:31

+0

此外,布尔和int不好,我得到一个'错误:变量“bitErrors”可能不会被初始化“。如果我用上面的本地语句替换它,我会得到'错误:一个参数不能被分配到一个指定的地址空间中。当然,我可以把它长度为1的阵列,但是这是不是真的最漂亮的解决方案...... :-) – user1111929 2012-01-17 07:49:13

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:从灰熊答案是足够好,它会更好,如果我可以发布它作为一个评论,但我对信誉策略限制。抱歉。

0

您也可以宣布你的阵列是这样的:

__local float LP[LENGTH]; 

而且通过长度为您的内核编译定义。

clBuildProgram(program, 0, NULL, "-DLENGTH=128", NULL, NULL); 
相关问题