2013-08-01 59 views
7

我想在我的OpenCL内核中创建一个本地数组,它的大小取决于内核的参数。看起来这是不被允许的 - 至少在AMD应用程序中。OpenCL中不允许使用变长数组声明 - 为什么?

您的体验与众不同吗?也许它只是APP?或者在这里有一些理由吗?

编辑:我现在建议可变长度数组也应该允许在CPU端代码中,这是C标准委员会的一个不幸的调用;但问题的立场。

回答

4

您可以动态分配本地块的大小。您需要将其作为内核的参数,并在调用clSetKernelArg时定义其大小。

定义的例子:

__kernel void kernelName(__local float* myLocalFloats, ...) 

主机代码:

clSetKernelArg(kernel, 0, myLocalFloatCount * sizeof(float), NULL); // <-- set the size to the correct number of bytes to allocate, but use NULL for the data. 

确保您知道本地内存的限制是你的设备上你这样做之前。调用clGetDeviceInfo,并轮询“CL_DEVICE_LOCAL_MEM_SIZE”值。

+1

这是我正在使用的解决方法,但是 - 因为这是可能的,为什么我不应该只能声明一个变长数组或者调用一些OpenCL malloc-like函数来分配一个本地数组? – einpoklum

+0

我认为它与现在的许多设备需要事先了解这些信息有关,因此他们可以安全地进行验证和分配。我还不知道AMD的GCN架构将支持gpu-side malloc调用。 – mfa

+0

如果这是允许的,那么你应该能够动态地分配内核内的设备内存,返回alloc错误等等,而这在GPU中是不可能的。在内核级别,一切都需要是静态的。正如他们所说,唯一的方法是从主机代码中设置它。 – DarkZeros

3

不知道为什么人们说你不能这样做,因为它是许多人用OpenCL做的事情(是的,我知道它不完全相同,但它在很多情况下运行得很好)。

由于OpenCL内核是在运行时编译的,就像文本一样,您可以简单地将大小设置为任意大小,然后重新编译内核。当你在大小上有很大的变化时,这显然不会是完美的,但通常我会在启动时编译几个不同的大小,然后根据需要调用正确的大小(基于内核参数)。如果我得到一个新的大小,我没有一个内核,我将编译它,然后缓存内核,以防它再次出现。

+0

嗯,是的,这确实开启了一些有趣的可能性,但我必须说我不明白为什么OpenCL内核是在运行时编译的,如果我可以编译我的主机代码尽管它可能是硬件专用的(x86_64比x86等),但我不明白为什么我的GPU代码不应该这样。无论如何,你会得到你的upvote .. – einpoklum

+0

我相信当硬件或驱动程序无法做到这些类型的东西时,就有灵活性。如果您只是在适度的努力下寻求主要的性能提升,并且在可能的情况下达到理论最大值,那么OpenCL非常适合。 (驾驶员有点头疼,但这总是与这些事情有关的问题,你找出他们的怪癖)。 –

相关问题