Floating point CUDA:将数据累积到一个大的浮动直方图中

Floating point CUDA:将数据累积到一个大的浮动直方图中,floating-point,cuda,atomic,histogram,Floating Point,Cuda,Atomic,Histogram,我正在考虑一种使用CUDA实现以下算法的方法: 处理大量体素,我为每个体素计算一个索引I和一个值c。计算之后,我需要执行直方图[I]+=c c是一个浮点值,直方图最多可包含15000个存储箱 我正在寻找一种使用CUDA高效实现此功能的方法。第一个明显的问题是,我使用的是compute capabilities 1.3,它甚至不能执行浮点的atomicAdd(),因此如何可靠地累积任何内容 做一些更简单的事情。直方图保存在共享内存中(由于其大小,我不能这样做),它只累加整数。这种方法可以推广到我的

我正在考虑一种使用CUDA实现以下算法的方法:

处理大量体素,我为每个体素计算一个索引
I
和一个值
c
。计算之后,我需要执行
直方图[I]+=c

c
是一个浮点值,直方图最多可包含15000个存储箱

我正在寻找一种使用CUDA高效实现此功能的方法。第一个明显的问题是,我使用的是compute capabilities 1.3,它甚至不能执行浮点的
atomicAdd()
,因此如何可靠地累积任何内容


做一些更简单的事情。直方图保存在共享内存中(由于其大小,我不能这样做),它只累加整数。这种方法可以推广到我的情况吗?

使用atomicAdd()直接对外部内存进行历史编程将非常低效。根据直方图的范围,您可能需要考虑通过源数据的多次传递,更新共享内存中的部分直方图,然后在每次传递后写出部分直方图。只要您不必对输入数据进行大量的传递,这应该会更有效率。显然,您希望根据可用共享内存的限制,使部分直方图尽可能大,以尽量减少所需的传递次数。

使用atomicAdd()直接对外部内存进行历史编程将非常低效。根据直方图的范围,您可能需要考虑通过源数据的多次传递,更新共享内存中的部分直方图,然后在每次传递后写出部分直方图。只要您不必对输入数据进行大量的传递,这应该会更有效率。显然,您希望根据可用共享内存的限制,使部分直方图尽可能大,以尽量减少所需的通过次数。

两步方法可能是最好的。您可以为体素子集创建多个直方图,并将它们相加形成全局直方图

假设您有N个体素,首先创建大小为M x 15000的全局设备内存(其中M 运行cuda内核计算每个线程索引的N/M个体素的直方图。
所有线程完成后,现在可以运行另一个cuda内核,对最终直方图的M直方图求和

两步法可能是最好的。您可以为体素子集创建多个直方图,并将它们相加形成全局直方图

假设您有N个体素,首先创建大小为M x 15000的全局设备内存(其中M 运行cuda内核计算每个线程索引的N/M个体素的直方图。
所有线程完成后,现在可以运行另一个cuda内核,对最终直方图的M直方图求和

这看起来是一种很有前途的方法,但如何确保没有两个线程同时写入同一个单元格?每个线程都有自己的直方图,使用第二个内核求和。唯一需要担心的是,在求和之前确保所有线程都已完成。这看起来是一种很有前途的方法,但如何确保没有两个线程同时写入同一个单元格?每个线程都有自己的直方图,使用第二个内核求和。唯一需要担心的是,在求和之前确保所有线程都已完成。