使用OpenCL优化本地内存使用

时间:2015-02-15 21:12:51

标签: memory-management opencl gpgpu

OpenCL当然是为了抽象出硬件实现的细节而设计的,因此在担心如何配置硬件方面过分掉兔子洞可能是一个坏主意。

话虽如此,我想知道有多少本地内存可用于任何特定内核。例如,如果我有一个包含64个工作项的工作组,那么可能不止一个工作组可能同时在计算单元内运行。但是,CL_DEVICE_LOCAL_MEM_SIZE查询返回的本地内存大小似乎适用于整个计算单元,而如果此信息是针对工作组则更有用。有没有办法知道如果它们在同一个计算单元上共存,有多少工作组需要共享同一个内存池?

我原以为确保我的工作组内存使用量低于本地内存总量的四分之一是一个好主意。这太保守了吗?是手动调整的唯一途径吗?对我来说,这意味着你只是在调整一个GPU模型。

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

2 个答案:

答案 0 :(得分:1)

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

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

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

AMD发布了一篇关于如何计算不同架构here的占用率的文章 NVIDIA提供了xls sheet来计算不同架构的占用率 并非所有用于计算的必要信息都可以通过OCL查询(如果我没记错的话),但没有什么能阻止您在应用程序中存储有关不同体系结构的信息。

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

这是非常严格的,使用 clGetKernelWorkGroupInfo ,您不需要这样做。但是,需要考虑 CL_KERNEL_LOCAL_MEM_SIZE 的内容:

  

如果是本地内存大小,则为内核的任何指针参数   用__local地址限定符声明,未指定,它   假设大小为0.

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

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

我想知道整个本地内存大小是否可用于本地内存的用户分配,或者是否有其他系统开销使其减少?

再次 CL_KERNEL_LOCAL_MEM_SIZE 就是答案。标准规定:

  

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

答案 1 :(得分:0)

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