CUDA(六). 从并行排序方法理解并行化思维——冒泡、归并、双调排序的GPU实现

在第五讲中我们学习了GPU三个重要的基础并行算法: Reduce, Scan 和 Histogram,分析了 其作用与串并行实现方法。 在第六讲中,本文以冒泡排序 Bubble Sort、归并排序 Merge Sort 和排序网络中的双调排序 Bitonic Sort 为例, 讲解如何从数据结构课上学的串行并行排序方法转换到并行排序,并附GPU实现代码。

在并行方法中,我们将考虑到并行方法需要注意的特点进行设计,希望大家在读完本文后对GPU上并行算法的设计有一些粗浅的认识。需注意的特点如下:
1. 充分发挥硬件能力(尽量不要有空闲且一直处于等待状态的SM)
2. 限制branch divergence(见CUDA系列学习(二))
3. 尽量保证内存集中访问(即防止不命中)

( 而我们在数据结构课上学习的sort算法往往不注意这几点。)




CUDA系列学习目录:

CUDA系列学习(一)An Introduction to GPU and CUDA

CUDA系列学习(二)CUDA memory & variables - different memory and variable types

CUDA系列学习(三)GPU设计与结构QA & coding练习

CUDA系列学习(四)Parallel Task类型 与 Memory Allocation

CUDA系列学习(五)GPU基础算法: Reduce, Scan, Histogram





I. Bubble Sort

冒泡排序,相信大家再熟悉不过了。经典冒泡排序通过n轮有序冒泡(n为待排序的数组长度)得到有序序列, 其空间复杂度O(1), 时间复杂度O(n^2)。

那么如何将冒泡排序算法改成并行算法呢? 这里就需要解除一些依赖关系, 比如是否能解除n轮冒泡间的串行依赖 & 是否能解除每一轮冒泡内部的串行依赖, 使得同样的n^2次冒泡操作可以通过并行, 降低step complexity。
1996年, J Kornerup针对这些问题提出了odd-even sort算法,并在论文中证明了其排序正确性。


I.1 从Bubble Sort到Odd-even Sort

先来看一下odd-even sort的排序方法:


这里写图片描述
图1.1

上图为odd-even sort的基本方法。
奇数步中, array中奇数项array[i]与右边的item(array[i + 1])比较;
偶数步中, array中奇数项array[i]与左边的item(array[i - 1]) 比较;

这样,同一个step中的各个相邻比较就可以并行化了

PS: 对于array中有偶数个元素的数组也是一样:


这里写图片描述
图1.2



I.2 Odd-even Sort复杂度

在odd-even sort的算法下, 原本O(n^2)的总比较次数不变,但是由于并行,时间复杂度降到O(n), 即

step complexity = O(n)
work complexity = O(n^2)

code详见 < Bubble sort and its variants >






II. Merge Sort

看过odd-even sort后,我们来看如何将归并排序并行化。数据结构课上我们都学过经典归并排序: 基于divide & conquer 思想, 每次将一个array分拆成两部分, 分别排序后合并两个有序序列。 可以通过 T(n)=2T(n/2)+n 得到, 其complexity = O(nlogn)。 和I.1节类似, 我们看看merge sort中的哪些步是可以并行的。

这里可以将基于merge sort的大规模数据排序分为三部分。 经过divide步之后, 数据分布如图所示:


这里写图片描述
图2.1

最下端的为 大量-短序列 的合并;
中间一块为中等数量-中等长度序列 的合并;
最上端的为少量-长序列 的合并;

我们分这三部分进行并行化。 之后大家会明白为啥要这么分~<

  • 33
    点赞
  • 151
    收藏
    觉得还不错? 一键收藏
  • 17
    评论
CUDA是一种并行计算平台和编程模型,专门用于NVIDIA的GPU加速计算。在CUDA中,可以通过多GPU并行来提高计算速度和性能。 首先,CUDA支持多GPU之间的数据传输和共享。多个GPU可以同时访问和操作同一块内存,通过数据传输和共享,可以在多个GPU之间共享计算任务和数据,从而减少数据传输的开销。这样,可以充分利用多个GPU的计算能力,提高并行计算的效率。 其次,CUDA的多GPU并行还通过任务划分和调度来实现。在多个GPU并行执行时,可以将计算任务划分为多个子任务,并同时在多个GPU上调度执行这些子任务。通过合理划分和调度,可以使得多个GPU同时进行计算,并将计算结果进行整合得到最终结果。这种任务划分和调度的方式能够充分发挥多GPU并行计算的优势,提高计算速度和效率。 此外,CUDA还提供了多GPU编程的接口和工具。开发者可以通过CUDA编程模型中的函数和工具,如CUDA Runtime API和CUDA标准库等,方便地进行多GPU并行编程。这些接口和工具提供了丰富的并行计算功能,可以帮助开发者更加高效地利用多个GPU的计算能力。 总的来说,CUDA的多GPU并行可以通过数据传输和共享、任务划分和调度以及多GPU编程接口和工具等方式来实现。通过充分利用多个GPU的计算能力和优势,可以加速并行计算任务的执行,提高计算速度和性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值