CUDA:还原还是原子操作?

Mar*_* A. 3 algorithm cuda matrix reduction gpu-atomics

我正在写一个CUDA内核,它涉及计算给定矩阵的最大值,我正在评估可能性.我能找到的最好方法是:

强制每个线程在共享内存中存储一​​个值,然后使用减少算法来确定最大值(pro:最小差异缺点:共享内存在2.0设备上限制为48Kb)

我无法使用原子操作,因为它有读取和写入操作,因此线程无法通过同步线程同步.

还有其他想法进入你的脑海吗?

pea*_*kxu 6

您可能还想使用CUDA Thrust附带的缩减例程,它是CUDA 4.0的一部分或在此处提供.

该库由一对nVidia工程师编写,与手工优化的代码相比具有优势.我相信还有一些网格/块大小的自动调整正在进行中.

您可以通过包装原始设备指针轻松地与您自己的内核连接.

这严格来自快速整合的观点.对于理论,请参阅tkerwin的答案.

  • 到目前为止,我更推荐 nVIDIA 的 [libcub](https://nvlabs.github.io/cub/)(由 Duane Merill 编写),而不是他们的推力。 (2认同)

Pav*_*ili 5

这是在 CUDA 中执行缩减的常用方法

在每个区块内,

1)为每个线程在共享内存中保持一个运行减少的值。因此,每个线程将从全局内存中读取 n(我个人喜欢在 16 到 32 之间),并更新这些值的减少值

2) 在块内执行归约算法,得到每个块的一个最终归约值。

这样你就不需要比(线程数)* sizeof(datatye)字节更多的共享内存。

由于每个块都有一个减少的值,您将需要执行第二次减少传递以获得最终值。

例如,如果您每个块启动 256 个线程,并且每个线程读取 16 个值,您将能够减少每个块 (256 * 16 = 4096) 个元素。

因此,如果有 100 万个元素,您将需要在第一遍中启动大约 250 个块,而在第二遍中只需要启动一个块。

对于此配置的元素数量 > (4096)^2 的情况,您可能需要第三次通过。

您必须注意合并全局内存读取。您不能合并全局内存写入,但这是您需要采取的一种性能损失。