如何在多GPU上实现Radix排序?

时间:2010-11-14 20:09:56

标签: concurrency parallel-processing cuda opencl gpu

如何在多GPU上实现基数排序 - 与单GPU相同,即通过拆分数据然后在单独的GPU上构建直方图,然后使用合并数据(如一堆卡片)?

2 个答案:

答案 0 :(得分:5)

该方法可行,但我认为这不是最快的方法。具体地,合并每K比特(K = 4当前最佳)的直方图将需要在GPU 32 / K = 8次之间交换密钥以对32位整数进行排序。由于GPU之间的内存带宽(~5GB / s)远低于GPU上的内存带宽(~150GB / s),因此会降低性能。

更好的策略是将数据拆分为多个部分,在不同的GPU上并行对每个部分进行排序,然后在最后合并这些部分。这种方法只需要一次GPU间转移(相对于上面的8次),因此速度会快得多。

答案 1 :(得分:1)

不幸的是,这个问题没有得到充分的解决。它取决于元素大小,元素在内存中开始生命的位置,以及您希望排序元素最终驻留的位置。

有时可以通过将元素存储在共享相同公共前缀的组中来压缩排序列表,或者您可以动态地使用唯一元素,将每个元素一次存储在已排序列表中并带有关联计数。例如,您可以将大量的32位整数列表分类为64K不同的16位值列表,将内存需求减半。

一般原则是您希望尽可能少地传递数据,并且您的吞吐量几乎总是与您的存储策略相关的带宽限制相对应。

如果您的数据集超过了快速内存的大小,您可能希望完成合并传递,而不是继续进行基数排序,因为另一个人已经回答了。

我刚刚进入GPU架构,我不理解上面的K = 4评论。我从来没有见过这样一个小型K会证明最佳的架构。

我怀疑合并直方图也是错误的做法。我可能会让元素在内存中碎片而不是合并直方图。难以在GPU架构中管理中等规模的分散/聚集列表吗?我当然希望不是。

最后,很难想出为什么要让多个GPU参与此任务的原因。假设您的卡有2GB内存和60GB / s写入带宽(这就是我的中档卡所显示的内容)。三通基数排序(11位直方图)需要6GB的写入带宽(可能是您的速率限制因子),或大约100ms来排序2GB的32位整数列表。好的,他们排序了,现在怎么样?如果您需要在没有任何预处理或压缩的情况下将它们运送到其他地方,则分拣时间将是小鱼。

无论如何,今天刚编译了我的第一个示例程序。还有很多东西值得学习。我的目标应用程序是排列密集型,这与排序密切相关。我相信将来我会再次讨论这个话题。