使用OpenCL优化本地内存的使用

3

当然,OpenCL旨在抽象硬件实现的细节,因此过于关注硬件配置可能是不明智的。

话虽如此,我想知道对于任何特定的内核使用多少本地内存才是有效的。例如,如果我的工作组包含64个工作项,则可能会有多个工作项同时在计算单元内运行。但是,似乎由 CL_DEVICE_LOCAL_MEM_SIZE 查询返回的本地内存大小适用于整个计算单元,而如果这些工作组共存于同一计算单元上,那么了解有多少工作组需要共享此同一内存池会更有用。是否有一种方法可以知道这种情况?

我曾经认为确保我的工作组内存使用量低于总本地内存大小的四分之一是个好主意。这太保守了吗?手动调整是唯一的方法吗?对我来说,这意味着你只为一个GPU型号进行调整。

最后,我想知道整个本地内存大小是否可供用户分配本地内存使用,或者是否存在其他系统开销使其减少?听说如果您分配太多,数据就会放入全局内存。是否有一种确定这种情况的方法?


你正在使用哪些设备?另外,你正在使用哪个OpenCL版本(1.0、1.1、1.2或2.0)?你有特定类型的内核想法吗?我认为没有一条经验法则适用于所有算法的最佳选择。 - mfa
我正在 Radeon HD 6750M 上测试 CL 1.2,但我希望更加全面地了解。 - Robotbugs
2个回答

1

有没有办法知道多少个工作组需要共享同一内存池,如果它们在同一个计算单元上共存?

不能一步到位,但可以计算。首先,您需要知道一个工作组需要多少本地内存。为此,您可以使用clGetKernelWorkGroupInfo和标志CL_KERNEL_LOCAL_MEM_SIZE(严格来说,这是一个内核所需的本地内存)。由于您知道每个计算单元中有多少本地内存,因此您可以知道最多可以在一个计算单元上共存的工作组数。

实际上,这并不简单。您必须考虑其他参数,例如可以驻留在一个计算单元上的最大线程数。
这是一个占用率问题(您应该尝试将其最大化)。不幸的是,占用率将取决于底层架构。

AMD发布了一篇关于如何计算不同架构的占用率的文章这里
NVIDIA提供了一个xls sheet,可以计算不同架构的占用率。
并非所有计算所需的信息都可以通过OCL查询(如果我没记错的话),但是您可以在应用程序中存储有关不同架构的信息。

我曾认为确保我的工作组内存使用量低于总本地内存大小的四分之一是个好主意。这太保守了吗?

这相当严格,而使用clGetKernelWorkGroupInfo,您无需这样做。但是需要考虑到CL_KERNEL_LOCAL_MEM_SIZE的某些内容:

如果未指定任何带有__local地址限定符的内核指针参数的本地内存大小,则其大小被假定为0。

由于您可能需要动态计算每个工作组所需的本地内存大小,因此这里有一个解决方法,基于内核是即时编译的事实。

您可以在内核文件中定义一个常量,然后使用 -D 选项在调用 clBuildProgram 时设置其值(先前计算)。

我想知道整个本地内存大小是否可供用户分配给本地内存,或者是否存在其他系统开销使其较少?

同样,CL_KERNEL_LOCAL_MEM_SIZE 是答案。标准规定:

这包括实现可能需要的本地内存,以执行内核...


0
如果您的工作相当独立且不重复使用输入数据,则可以安全地忽略有关工作组和共享本地内存的所有内容。但是,如果您的工作项可以共享任何输入数据(经典示例是重新读取输入数据的3x3或5x5卷积),则最佳实现将需要共享本地内存。非独立工作也可以受益。一种思考共享本地内存的方法是程序员管理的缓存。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接