并行正则采样排序算法及在 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 项目里得到了广泛的使用。
如果对 Mars 感兴趣,可以关注 Mars 团队专栏,或者钉钉扫二维码加入 Mars 讨论群。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
当 Mars 遇上 RAPIDS:用 GPU 以并行的方式加速数据科学
背景 在数据科学世界,Python 是一个不可忽视的存在,且有愈演愈烈之势。而其中主要的使用工具,包括 Numpy、Pandas 和 Scikit-learn 等。 Numpy Numpy 是数值计算的基础包,内部提供了多维数组(ndarray)这样一个数据结构,用户可以很方便地在任意维度上进行数值计算。 我们举一个蒙特卡洛方法求解 Pi 的例子。这背后的原理非常简单,现在我们有个半径为1的圆和边长为2的正方形,他们的中心都在原点。现在我们生成大量的均匀分布的点,让这些点落在正方形内,通过简单的推导,我们就可以知道,Pi 的值 = 落在圆内的点的个数 / 点的总数 * 4。 这里要注意,就是随机生成的点的个数越多,结果越精确。 用 Numpy 实现如下: import numpy as np N = 10 ** 7 # 1千万个点 data = np.random.uniform(-1, 1, size=(N, 2)) # 生成1千万个x轴和y轴都介于-1和1间的点 inside = (np.sqrt((data ** 2).sum(axis=1)) < 1).sum() # 计...
- 下一篇
Mars 开源月报(2020.3)
本月,Mars 发布了 0.4.0b1 ,0.4.0b2 和 0.3.2 以及 0.3.3,点击链接查看详细的 Release Notes。本月两次发布版本是特殊情况,0.4.0b2 修复了 0.4.0b1 中比较紧急的问题。 Mars 项目发布周期 这里先简述下 Mars 的版本发布周期。Mars 以一个月为发布周期,采用双版本发布策略,一般会同时发布 Pre-release 版本和正式版。Pre-release 版本里会包含更多激进的功能或改动,可能会不稳定,而开发中我们认为稳定的功能或增强会被同步到正式版里。 查看 Github 项目的 milestones 可以看到最新的 Pre-release 和正式版本。 查看 Github Projects 页面 可以看到归类的 issues 和 PRs。 v0.4 Release 是我们按版本归档的进行中的 issues 和 PRs。其他则是按模块划分。 新版本功能 Highlight 新版本我们花了大量时间来完善 DataFrame API,经过这个版本的努力,pandas 中的一些常见的接口都得到了支持。 更完善的聚合和分组聚合 #...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7安装Docker,走上虚拟化容器引擎之路
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS8编译安装MySQL8.0.19
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS关闭SELinux安全模块
- CentOS7设置SWAP分区,小内存服务器的救世主
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- CentOS8安装Docker,最新的服务器搭配容器使用