【问题标题】:Quick sort in GLSL?GLSL中的快速排序?
【发布时间】:2009-04-05 11:44:19
【问题描述】:

我正在考虑使用 GLSL 着色器将大量处理移植到 GPU。我偶然发现的一个直接问题是,在其中一个步骤中,算法需要维护一个元素列表,对它们进行排序并取几个最大的元素(哪个数字取决于数据)。在 CPU 上,这只是使用 STL 向量和 qsort() 来完成,但在 GLSL 中我没有这样的设施。有没有办法解决这个缺陷?

【问题讨论】:

  • 不知GPU是否擅长快速排序...

标签: opengl glsl gpgpu quicksort


【解决方案1】:

披露:我真的不知道 GLSL——我一直在使用 AMD Stream SDK 进行 GPGPU 编程,它有不同的编程语言。

根据您对 Bjorn 的回答的评论,我推测您对使用 GPU 对庞大的数据库进行排序(例如创建反向电话簿或其他什么)感兴趣,但相反,您有一个小数据集,每个片段都有自己的数据集进行排序。更像是尝试进行中值像素过滤?

我只能笼统地说:

对于小型数据集,排序算法真的无关紧要。虽然人们一直在担心哪种算法对于超大型数据库来说是最好的排序算法,但对于小 N 来说,使用快速排序、堆排序、基数排序、壳排序、优化冒泡排序、未优化冒泡排序、等等。至少它在 CPU 上并不重要。

GPU 是 SIMD 设备,因此它们希望每个内核以锁步执行相同的操作。计算很便宜,但分支很昂贵,并且每个内核以不同方式分支的数据相关分支非常、非常、非常、昂贵。

因此,如果每个内核都有自己的小数据集进行排序,并且要排序的数据数量取决于数据,并且每个内核可能是不同的数字,那么您最好选择一个最大大小(如果可以),用 Infinity 或某个大数填充数组,并让每个内核执行完全相同的排序,这将是未优化的无分支冒泡排序,如下所示:

伪代码(因为我不懂 GLSL),大概 9 分

#define TwoSort(a,b) { tmp = min (a, b); b = a + b - tmp; a = tmp; }
for (size_t n = 8; n ; --n) {
  for (size_t i = 0; i < n; ++i) {
    TwoSort (A[i], A[i+1]);
  }
}

【讨论】:

  • 非常好。这正是我一直在寻找的。数据依赖分支的缺点你有参考吗?
  • 我没有想到任何参考资料。顺便说一句,快速排序无法在 GPU 上运行的另一个原因是它们不支持递归。
  • 递归只是另一个循环。所以几乎所有的递归情况都可以重写为 While/For 循环。
  • AFAIK 并非所有 GLSL 编译器和 GPU(特别是 OpenGL ES 平台上的那些)都支持动态边界循环。
【解决方案2】:

你看过这篇文章吗? https://developer.nvidia.com/gpugems/GPUGems2/gpugems2_chapter46.html

我不确定您是在寻找快速排序算法还是快速排序算法。文中的算法使用归并排序...

【讨论】:

  • 是的,我认为 MergeSort 在 SIMD 平台上运行(由于内存本地化)比 QuickSort 更有意义。
  • 我宁愿寻找一次完整的排序,因为排序只是我算法中的一个步骤,应该对每个片段都运行。
  • 很好的答案。文章中的算法很好。双音分拣机 FTW :-)
【解决方案3】:

我对 GPU 编程一无所知。

我会使用堆排序而不是快速排序,因为您说您只需要查看前几个值。堆可以在O(n)时间构建,但获得最高值是log(n)。因此,如果您需要的值的数量明显小于元素的总数,您可以获得一些性能。

【讨论】:

    猜你喜欢
    • 2020-08-14
    • 2014-10-10
    • 2016-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-08
    • 2012-08-23
    • 1970-01-01
    相关资源
    最近更新 更多