我正在尝试使用CUDA实现以下算法的方法:
处理大量体素,对于每个体素,我计算索引i
和值c
。在计算之后,我需要执行histogram[i] += c
c
是一个浮点值,直方图最多可以有15,000个箱。
我正在寻找一种使用CUDA有效实现这一目标的方法。第一个明显的问题是,对于我正在使用的计算能力1.3,我甚至不能做atomicAdd()
浮点数,那么我怎样才能可靠地积累任何东西?
This example by nVidia做的事情有点简单。直方图保存在共享内存中(由于其大小,我无法做到),它只会累积整数。这种方法可以推广到我的案例吗?
答案 0 :(得分:1)
两步法可能是最好的。您可以为体素子集创建多个直方图,并将它们全部加起来以获得全局直方图
假设您有N个体素,首先创建大小为M x 15000的全局设备内存(其中M 运行cuda kernal以计算每个线程索引的N / M个体素数的直方图。
完成所有线程后,您现在可以运行另一个cuda核心,它将M直方图与最终直方图相加。
答案 1 :(得分:0)
使用atomicAdd()直接对外部存储器进行直方图编程效率非常低。根据直方图的范围,您可能需要考虑多次遍历源数据,更新共享内存中的部分直方图,然后在每次通过后写出部分直方图。只要您不必通过输入数据进行大量传递,这应该更有效率。显然,您需要根据可用共享内存的限制使部分直方图尽可能大,以尽量减少所需的传递次数。