您现在的位置是:首页 > 文章详情

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

日期:2020-04-12点击:520

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

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

PSRS 算法过程

image

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 项目里得到了广泛的使用。

如果对 Mars 感兴趣,可以关注 Mars 团队专栏,或者钉钉扫二维码加入 Mars 讨论群。

IMG_8215

原文链接:https://yq.aliyun.com/articles/754853
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章