【问题标题】:What is a good sorting algorithm on CUDA?什么是 CUDA 上好的排序算法?
【发布时间】:2016-08-01 12:04:01
【问题描述】:

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

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

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

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

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

【问题讨论】:

  • 只对一个小数组进行排序,无论哪种方式,您都无法使 GPU 饱和。可能更容易对 CPU 端进行排序,特别是如果您同时运行其他内核。但是,如果您有很多小列表(最多约 500 个项目),类似的问题是与订单无关的透明度。见this。您需要提取键和索引列表,对它们进行排序,然后使用索引重新排序或仅按排序顺序读取。

标签: sorting cuda


【解决方案1】:

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

我认为“大”是指大于 1M 的元素,而小 --- 小到足以实际放入共享内存(可能小于 1K 元素)。如果我对“小”的理解与您的一致,我会尝试以下方法:

  • 仅使用单个块对数组进行排序(它可以成为更大 CUDA 内核的一部分)
  • 双调排序是可用于并行算法的一种很好的方法。

一些关于双调排序的页面:

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

我曾经也为单个 warp 实现了冒泡排序(哈哈!),以对 32 个元素的数组进行排序。由于它的简单性,它实际上并没有表现得那么糟糕。不过,经过良好调整的双调排序仍然会执行得更快。

【讨论】:

  • “我曾经也实现了冒泡排序” - 你真要下地狱了!
  • 插入和冒泡排序在 GPU 上非常有用,甚至可以处理 100 个项目。低 SIMD 散度。 Bitonic 很好,但你必须有 2^n 个项目,或者下面的项目不多(即 513,而且相当慢)。
【解决方案2】:

使用CUDPPThrust 库中可用的排序调用。

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

【讨论】:

  • cudpp 有归并排序和基数排序,顺便说一下。
【解决方案3】:

您究竟为什么要走向 CUDA?我的意思是,听起来你的问题不是其中之一,CUDA 非常擅长。您只想对包含 512 个元素的数组进行排序,并让一些指针指向另一个位置。这没什么花哨的,为此使用简单的串行算法,例如快速排序、堆排序或合并排序。

此外,请考虑将数据从堆/堆栈复制到 CUDA 设备所需的开销。使用 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 在具有大向量和矩阵以及相当简单的数据类型(数字)的数学计算方面非常强大,因为它是 GPU 上经常出现的问题之一:计算图形。

【讨论】:

    【解决方案4】:

    是的,我完全同意,对小数组(

    【讨论】:

    • 有时你会在 CUDA 上解决一个更大的问题,而那些(有时是几个)需要排序的小数组可能是你代码的“副产品”。在这种情况下,在 CUDA 上执行此操作是完全有效的,而不是使用 CPU 将这些内容发送到主机,然后再返回 GPU。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-01
    • 2020-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-26
    • 2010-10-11
    相关资源
    最近更新 更多