【问题标题】:Optimizing local memory use with OpenCL使用 OpenCL 优化本地内存使用
【发布时间】:2015-04-16 08:41:51
【问题描述】:

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

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

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

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

【问题讨论】:

  • 您正在使用哪些设备?另外,您使用的是什么 opencl 版本(1.0、1.1、1.2 或 2.0)?您是否想到了特定类型的内核?我认为没有一个经验法则对所有算法都是最佳的。
  • 嗯,我正在 Radeon HD 6750M 上测试 CL 1.2,但我希望能更全面地了解。

标签: memory-management opencl gpgpu


【解决方案1】:

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

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

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

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

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

这是相当严格的,使用 clGetKernelWorkGroupInfo 您不需要这样做。然而,有一些关于 CL_KERNEL_LOCAL_MEM_SIZE 的事情需要考虑:

如果是本地内存大小,对于内核的任何指针参数 使用 __local 地址限定符声明,未指定,其 大小假定为 0。

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

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

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

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2011-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-27
      • 2016-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多