3

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

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

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

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

我觉得这种方法不合适。感觉更像是一个黑客。

大家有遇到过这种情况吗?你的解决方案是什么?

4

2 回答 2

2

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

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

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

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

    • Launch your kernel with plenty of work-groups so that, while some are busy waiting on global memory accesses, others can be scheduled on the multiprocessors ("latency hiding").
    • Coalesce global memory access as far as your vendor supports this. The NVidia OpenCL Best Practice guide goes into some detail, and the >100% performance improvements are very achievable.
于 2012-11-08T16:56:46.380 回答
1

你的方法似乎还可以。

您可以查看NVidias OpenCL 最佳实践指南。在第 3.2.2 节 - “共享内存” - 有一个矩阵乘法的例子。每个工作组将所需数据从全局内存复制到本地内存。

于 2012-11-07T21:51:25.417 回答