110 likes | 694 Views
基于 MPI 的 PSRS 并行排序算法的实现. 09 国土王信. 什么是并行计算. 传统上,一般的软件设计都是串行式计算: 软件在一台只有一个 CPU 的电脑上运行; 问题被分解成离散的指令序列; 指令被一条接一条的执行; 在任何时间 CPU 上最多只有一条指令在运行 在最简单的情形下,并行计算是使用多个计算资源去解决可计算问题。 用多核 CPU 来运行; 问题被分解成离散的部分可以被同时解决; 每一部分被细分成一系列指令; 每一部分的指令可以在不同的 CPU 上同时的执行;.
E N D
基于MPI的PSRS并行排序算法的实现 09国土王信
什么是并行计算 • 传统上,一般的软件设计都是串行式计算: • 软件在一台只有一个CPU的电脑上运行; • 问题被分解成离散的指令序列; • 指令被一条接一条的执行; • 在任何时间CPU上最多只有一条指令在运行 • 在最简单的情形下,并行计算是使用多个计算资源去解决可计算问题。 • 用多核CPU来运行; • 问题被分解成离散的部分可以被同时解决; • 每一部分被细分成一系列指令; • 每一部分的指令可以在不同的CPU上同时的执行;
MPI简介: MPI 是为开发基于消息传递模型的并行程序而制定的工业标准,其目的是为了提高并行程序的可移植性和易用性,用户必须显式地通过发送和接受消息来实现处理器之间的数据交换。 MPI只是一个并行编程语言标准,要编写基于MPI 的并行程序,还必须借助MPI的某种具体实现。MPICH 是最重要的一种MPI 实现,是一个与MPI 规范同步发展的版本 • 基于MPI 的程序设计方法 : 并行程序设计可以通过多种方法实现,它们各有特点,并适合于不同的场合。最常用的是共享变量方法和消息传递方法。共享变量方法的主要特点是利用共享存储器中共享变量来实现处理机间的通信,它主要用在共享存储结构中。其中进程的分配、结果的收集均通过消息传递来完成
PSRS算法原理 • 并行正则采样排序,简称PSRS (Parallel Sorting by Regular Sampling),它是一种基于均匀划分(Uniform Partition)原理的负载均衡的并行排序算法。 • 假定待排序的元素有n个,系统中有p个处理器,那么系统首先将n个元素均匀地分割成p段,每段含有n /p个元素,每段指派一个处理器,然后各个处理器同时施行局部排序。为了使各段中诸局部有序的元素在整个序列中也能占据正确的位置,那么就首先从各段中抽取几个代表元素,再从他们产生出p-1个主元,然后按这些主元与原各局部有序中的元素之间的偏序关系,将各个局部有序段划分成p段,接着通过全局交换将各个段中的对应部分集合在一起,最后将这些集合在一起的各部分采用多路归并的方法进行排序,这些有序段汇合起来就自然成为全局有序序列了。
算法描述 • 设有n个数据,P个处理器,以及均匀分布在P个处理器上的n个数据。 则PSRS算法可描述如下: • 算法1 PSRS排序算法 • 输入:n个待排序的数据,均匀地分布在P个处理器上 • 输出:分布在各个处理器上,得到全局有序的数据序列 • Begin • (1) 每个处理器将自己的n/P个数据用串行快速排序(Quicksort),得到一个排好序的序列; • (2) 每个处理器从排好序的序列中选取第w,2w,3w,…,(P-1)w个共P-1个数据作为代表元素,其中w=n/P2; • (3) 每个处理器将选好的代表元素送到处理器P0中,并将送来的P段有序的数据序列做P路归并,再选择排序后的第P-1,2(P-1),…,(P-1)(P-1)个共P-1个主元; • (4) 处理器P0将这P-1个主元播送到所有处理器中; • (5) 每个处理器根据上步送来的P-1个主元把自己的n/P个数据分成P段,记 为处理器Pi的第j+1段,其中i=0,…,P-1,j=0,…,P-1; • (6) 每个处理器送它的第i+1段给处理器Pi,从而使得第i个处理器含有所有处理器的第i段数据(i=0,…,P-1); • (7) 每个处理器再通过P路归并排序将上一步的到的数据排序;从而这n个数据便是有序的。
代码描述 • 每个处理器将自己的n/P个数据用串行快速排序(Quicksort),得到一个排好序的序列 • quicksort(arr,0,mylength - 1); • MPI_Barrier( MPI_COMM_WORLD); • 每个处理器从排好序的序列中选取第w,2w,3w,…,(P-1)w个共P-1个数据作为代表元素,其中w=n/P2 • n = (int)(mylength/(Spt+1)); • for (i=0;i<Spt;i++) • temp1[i] = arr[(i+1)*n-1];
*每个处理器将选好的代表元素送到处理器P0中 • for (i=1;i<SumID;i++) • MPI_Irecv(&temp1[i*Spt], sizeof(int)*Spt,MPI_CHAR, i,ALLTOONE_TYPE+i, MPI_COMM_WORLD, &request[j++]); //该函数递交一个消息接收请求,要求MPI 系统在后台完成消息的接收。 • MPI_Waitall(SumID-1, request, status);//等待SumID个请求全部完成然后返回。 • 处理器P0将上一步送来的P段有序的数据序列做P路归并,再选择排序后的第P-1,(P-1),…,(P-1)(P-1)个共P-1个主元MPI_Barrier(MPI_COMM_WORLD); • quicksort(temp1,0,SumID*Spt1); • MPI_Barrier(MPI_COMM_WORLD); • for (i=1;i<Spt+1;i++) • temp1[i] = temp1[i*Spt-1];
处理器P0将这P-1个主元播送到所有处理器中 • MPI_Bcast(temp1, sizeof(int)*(1+Spt), MPI_CHAR, 0,MPI_COMM_WORLD);//通信器comm中进程号为的进程(称为根进程)将自己temp1中的内容发送给通信器中所有其他进程 • 每个处理器根据上步送来的P-1个主元把自己的n/P个数据分成P段,记为处理器Pi的第j+1段,其中i=0,…,P-1,j=0,…,P-1 • 每个处理器送它的第i+1段给处理器Pi,从而使得第i个处理器含有所有处理器的第i段数据(i=0,…,P-1); • 每个处理器再通过P路归并排序将上一步的到的数据排序;从而这n个数据便是有序的。
从运行结果可以看到使用6个进程时的计算速度反而不如用3个和4个进程运行时的速度,甚至在10个数的时候还不如1个进程。这是由于本程序的计算规模不大,另外引入一个进程的开销大于程序并行所带来的益处,所以进程数越多反而程序的运行速度越慢。 但我们可以观察随着数据量的增多线程数越多其消耗时间比越小。
利用MPI实现并行排序的感想 • MPI是针对分布式计算机系统提出的,它采用非共享内存的方式利用多进程完成并行任务,当计算规模不大或处理器数量不多时,更多进程的维护会增加系统的开销,而且进程之间的通信存在延时。它比较适合集群计算机系统 • 在并行计算中,如果各个处理器上的工作所需要的完成时间不同,则会使先完成工作的处理器等待未完成工作的处理器,浪费了计算资源。
谢谢! END!