并行正则采样排序算法及在 Mars 中的应用

相信大家对排序算法都非常熟悉了,快速排序、堆排序、归并排序等等。如果我们想在一个很大的数据集上进行排序,能利用上多核,甚至是分布式集群,有什么办法么?

本文就介绍一种并行排序算法:并行正则采样排序算法(Parallel Sorting by Regular Sampling),简称 PSRS 算法。

 

PSRS 算法过程

 

 

PSRS 算法的整个过程分为四步,如图所示,我们拆解开来讲。

现在假设我们有一个数组,有 48 个元素,现在数据被分成4份,即有4个分区。

 

阶段1,每个分区分别排序,并正则采样

我们对每个分区的数据调用快速排序,这样每个分区都是排好的数据。接着,我们从排好序的数据里正则采样4个数据。所谓正则,即有规律的,这里我们就每隔4个元素采样一个元素。

 

阶段2,归并采样数据,选出关键点

前面四个分区产生了4份采样数据,收集之,然后调用归并排序让他们有序。接着,我们从中选出 p - 1 (p 是分区个数)个关键点,这里还是正则采样的方式。

 

阶段3,数据分区

此时将关键点数据广播给每个分区,每个分区就可以根据关键点,将数据分成4份,使得每个数据落在各自的范围内。

 

阶段4,合并数据,归并排序

最后一个阶段是一个 shuffle 阶段,即每个下游都依赖前面的所有上游。此时每个分区将上游分好的数据收集起来,最终再进行一个归并排序。这样,我们最终的结果就是整体排序的了。

整个过程中,阶段1、阶段3 和 阶段4 可以并行。

MPI 的实现可以参考这里

 

PSRS 算法在 Mars 中的应用

Mars 以并行和分布式化 Python 数据科学栈为目标,PSRS 算法能很好解决并行排序问题,因此,Mars 中和排序有关的操作都是基于 PSRS 算法实现的。

以张量排序为例。

首先我们通过 Numpy 创建 1 亿个元素的数组。

 
 

In [1]: import numpy as np In [2]: a = np.random.rand(1_0000_0000) In [3]: a.nbytes Out[3]: 800000000

我们来看看使用 Numpy 的排序需要多久。

 
 

In [4]: %time np.sort(a) CPU times: user 10.8 s, sys: 394 ms, total: 11.2 s Wall time: 9.4 s Out[4]: array([1.05764619e-10, 5.86309734e-09, 1.76225879e-08, ..., 9.99999976e-01, 9.99999983e-01, 9.99999998e-01])

接着,我们来看看基于 PSRS 算法的 Mars tensor 排序需要多长时间。

 
 

In [10]: t = mt.tensor(a, chunk_size=1500_0000) In [12]: %time mt.sort(t).execute() CPU times: user 18.7 s, sys: 7.03 s, total: 25.7 s Wall time: 2.66 s

在我的笔记本上,可以看到 Numpy 的排序时长是 Mars 的 3.53 倍。

 

总结

本文介绍了并行正则排序算法,这个算法也在 Mars 项目里得到了广泛的使用。

上云就看云栖号:更多云资讯,上云案例,最佳实践,产品入门,访问:https://yqh.aliyun.com/

本文为阿里云原创内容,未经允许不得转载。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值