【问题标题】:Dealing with temporary matrices and private memory inside OpenCL kernels处理 OpenCL 内核中的临时矩阵和私有内存
【发布时间】:2012-11-06 15:33:34
【问题描述】:

我目前正在将一个相当哈利匹配的追踪算法(它是更大的图像处理算法的一部分)迁移到 OpenCL。

该算法使用一些内部矩阵和向量进行处理。其中一半的大小相当小(少于 10 列),但另一半可能会变得相当大,具体取决于输入矩阵(n * n、2n * n 等)。

所有内部矩阵的定义取决于输入矩阵。

鉴于标准中没有本地分配功能,我通过将内存块从全局内存映射到工作项的私有内存来解决内存问题。我确保在上下文设置期间块不重叠,以便在运行时确保数据一致性。

我觉得这种方法不合适。感觉更像是 hack。

你们中有人遇到过这种情况吗?你的解决方案是什么?

【问题讨论】:

  • 好的。你能把它迁移到那里吗?还是我应该在 SO 上重新发布?
  • 我认为版主可以;我会标记它,以便引起他们的注意。
  • Paul,您能否澄清一下您所说的将块从全局内存映射到私有内存时的意思?你的意思是你在你的函数中声明一个数组并从作为内核参数传递的全局指针复制数据到它?
  • 我不复制数据(即使由于局部性可能会提高速度),我只是将全局数据拆分为工作项专门用作它们之间的约定的区域核心。全局内存中的一个大缓冲区,分为全局工作大小块。希望能解决问题。

标签: image-processing matrix opencl signal-processing


【解决方案1】:

像这样分割全局内存缓冲区很好,尽管通常只用于输出回主机。全局内存访问通常需要数百个指令周期,因此我建议您:

  1. 改为在 __private 或 __local 内存中分配临时数据。后者检查 CL_DEVICE_LOCAL_MEM_SIZE,通常为 16KB-64KB。请记住,多处理器上的 __local 内存是跨工作组共享的;如果您使用太多,即使在 CL_DEVICE_LOCAL_MEM_SIZE 限制内,也会对多处理器的占用率产生负面影响,从而影响您的吞吐量。观察这一点的最佳方法是在您的工作负载 + 设备上进行实验。

  2. 如果您的临时矩阵对于 __local 内存来说太大了,请考虑是否可以将每个工作项缩小,以使其适合并避免全局内存的大量开销。

  3. 如果对每个工作项的最小数据占用有一些硬性限制,请按照您的描述使用 __global 内存。但是请确保您:

    • 使用大量工作组启动您的内核,这样当一些工作组忙于等待全局内存访问时,其他工作组可以安排在多处理器上(“延迟隐藏”)。
    • 在您的供应商支持的情况下合并全局内存访问。 NVidia OpenCL 最佳实践指南介绍了一些详细信息,超过 100% 的性能提升是非常可实现的。

【讨论】:

  • 感谢您的回答。 “请记住,多处理器上的 __local 内存是跨工作组共享的”——我认为 __local 内存在工作项而不是工作组之间共享。这就是你上面那句话的意思吗?
  • 抱歉可以更清楚。我的意思是,虽然 __local 变量只能在工作组内访问,但支持它的物理内存在多个工作组之间共享。因此,如果您指定一个大小为整个 CL_DEVICE_LOCAL_MEM_SIZE 的内核 __local 参数,则一次只能在多处理器上调度一个工作组。这通常会损害您的整体吞吐量。
【解决方案2】:

你的方法似乎没问题。

你可以看看NVidias OpenCL best practice guide。在第 3.2.2 节 - “共享内存” - 有一个矩阵乘法的例子。每个工作组将所需数据从全局内存复制到本地内存中。

【讨论】:

    猜你喜欢
    • 2018-12-27
    • 1970-01-01
    • 1970-01-01
    • 2012-12-14
    • 1970-01-01
    • 2023-04-03
    • 2019-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多