正确的方式通知OpenCL内核的许多内存对象?

int*_*t3h 7 gpgpu opencl

在我的OpenCL程序中,我将最终得到60多个全局内存缓冲区,每个内核都需要能够访问.让每个内核知道每个缓冲区的位置的推荐方法是什么?

缓冲区本身在应用程序的整个生命周期中都是稳定的 - 也就是说,我们将在应用程序启动时分配缓冲区,调用多个内核,然后仅在应用程序端解除分配缓冲区.但是,它们的内容可能会随着内核从它们读/写而改变.

在CUDA中,我这样做的方法是在我的CUDA代码中创建60多个程序范围全局变量.然后,我会在主机上写入我分配到这些全局变量中的设备缓冲区的地址.然后内核将简单地使用这些全局变量来查找它需要使用的缓冲区.

在OpenCL中执行此操作的最佳方法是什么?似乎CL的全局变量与CUDA略有不同,但我无法找到关于我的CUDA方法是否有效的明确答案,如果是的话,如何将缓冲区指针转换为全局变量.如果那不起作用,那么最好的方法是什么呢?

Rya*_*cus 2

60 个全局变量确实很多!您确定没有办法重构您的算法以使用较小的数据块吗?请记住,每个内核应该是一个最小的工作单元,而不是巨大的东西!

然而,有一种可能的解决方案。假设您的 60 个数组的大小已知,您可以将它们全部存储到一个大缓冲区中,然后使用偏移量来访问该大数组的各个部分。这是一个非常简单的示例,包含三个数组:

A is 100 elements
B is 200 elements
C is 100 elements

big_array = A[0:100] B[0:200] C[0:100]
offsets = [0, 100, 300]
Run Code Online (Sandbox Code Playgroud)

然后,您只需将 big_array 和偏移量传递给内核,就可以访问每个数组。例如:

A[50] = big_array[offsets[0] + 50]
B[20] = big_array[offsets[1] + 20]
C[0] = big_array[offsets[2] + 0]
Run Code Online (Sandbox Code Playgroud)

我不确定这会如何影响您特定设备上的缓存,但我最初的猜测是“不好”。这种数组访问也有点令人讨厌。我不确定它是否有效,但是您可以使用一些代码来启动每个内核,这些代码提取每个偏移量并将其添加到原始指针的副本中。

在主机端,为了使数组更易于访问,您可以使用 clCreateSubBuffer:http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateSubBuffer.html这也允许您可以传递对特定数组的引用,而无需偏移量数组。

我认为这个解决方案不会比传递 60 个内核参数更好,但根据您的 OpenCL 实现的 clSetKernelArgs,它可能会更快。它肯定会减少你的参数列表的长度。