在CUDA上有什么好的排序算法?

时间:2011-03-13 11:05:20

标签: sorting cuda

我有一个struct数组,我需要根据struct(N)的属性对这个数组进行排序。该对象如下所示:

 struct OBJ
 { 
   int N; //sort array of OBJ with respect to N
   OB *c; //OB is another struct
 } 

数组大小很小,大约512个元素,但每个元素的大小都很大,因此我无法将数组复制到共享内存。

对此数组进行排序的最简单,最好的方法是什么?我不需要一个需要大量时间来实现的复杂算法(因为数组中的元素数量很少)我只需要一个简单的算法。

注意:我已经阅读了一些关于使用GPU排序算法的论文,但这些论文的速度增益仅在阵列大小非常大时出现。因此我没有尝试实现他们的算法,因为我的数组的大小很小。我只需要一种简单的方法来并行排序我的数组。感谢。

4 个答案:

答案 0 :(得分:5)

什么意思是“大”和“小”?

通过“大”我假设你的意思是> 1M元素,而小 - 小到足以实际适合共享内存(可能是< 1K元素)。如果我对“小”的理解与你的相符,我会尝试以下方法:

  • 只使用一个块对数组进行排序(它可以是一些更大的CUDA内核的一部分)
  • Bitonic排序是并行算法可以采用的优秀算法之一。

有关bitonic排序的一些页面:

  • Bitonic sort(很好的解释,可视化的applet和不占用太多空间的java源码)
  • Wikipedia(对我的口味有点太简短的解释,但更多源代码 - 一些抽象语言和Java)
  • NVIDIA code Samples(CUDA中的一个示例源。我认为它有点过于专注于杀死银行冲突。我相信更简单的代码实际上可能会更快执行)

我曾经为单个warp实现了一个冒泡排序(lol!)来排序32个元素的数组。由于其简单性,它实际上并没有那么糟糕。一个调整好的bitonic排序仍然会表现得更快。

答案 1 :(得分:1)

为什么你要走向CUDA?我的意思是,它闻起来像你的问题不是其中之一,CUDA非常擅长。您只想对512个元素的数组进行排序,并让一些指针引用另一个位置。这没什么特别的,使用简单的串行算法,例如Quicksort,Heapsort或Mergesort。

此外,请考虑将数据从堆/堆栈复制到CUDA设备所需的开销。当计算足够强大以至于COMPUTING_TIME_ON_CUDA+COPY_DATA_FROM_HEAP_TO_CUDA_DEVICE+COPY_DATA_FROM_CUDA_DEVICE_TO_HEAP < COMPUTING_TIME_ON_HOST_CPU时,使用CUDA才有意义。

此外,CUDA在使用大向量和矩阵以及相当简单的数据类型(数字)进行数学计算时非常强大,因为它是GPU上经常出​​现的问题之一:计算图形。

答案 2 :(得分:0)

是的我完全同意,排序小数组(&lt; 5k元素)的开销会使用CUDA中实现的“微调”并行排序算法实现可能的加速。我更喜欢基于CPU的排序这么小的尺寸......

答案 3 :(得分:0)

使用CUDPPThrust库中提供的排序调用。

如果您使用 cudppSort ,请注意它仅适用于整数或浮点数。要对结构数组进行排序,可以先将键与索引数组一起排序。稍后,您可以使用已排序的索引数组将结构移动到其最终的排序位置。我已经在博客文章here中描述了如何为cudppCompact压缩算法执行此操作。使用cudppSort对结构数组进行排序的步骤类似。