MPI编程简单介绍

第三章 MPI编程

 

3.1 MPI简单介绍

多线程是一种便捷的模型,当中每一个线程都能够訪问其他线程的存储空间。因此,这样的模型仅仅能在共享存储系统之间移植。一般来讲,并行机不一定在各处理器之间共享存储,当面向非共享存储系统开发并行程序时,程序的各部分之间通过来回传递消息的方式通信。要使得消息传递方式可移植,就须要採用标准的消息传递库。这就促成的消息传递接口(Message Passing Interface, MPI)的面世,MPI是一种被广泛採用的消息传递标准[1]

OpenMP并行程序不同,MPI是一种基于消息传递的并行编程技术。消息传递接口是一种编程接口标准,而不是一种详细的编程语言。简而言之,MPI标准定义了一组具有可移植性的编程接口。各个厂商或组织遵循这些标准实现自己的MPI软件包,典型的实现包含开放源码的MPICHLAM MPI以及不开放源码的Intel MPI。因为MPI提供了统一的编程接口,程序猿仅仅须要设计好并行算法,使用对应的MPI库就能够实现基于消息传递的并行计算。MPI支持多种操作系统,包含大多数的类UNIXWindows系统。

3.1.1怎样实现MPI

MPI是一个标准。它不属于不论什么一个厂商,不依赖于某个操作系统,也不是一种并行编程语言。不同的厂商和组织遵循着这个标准推出各自的实现,而不同的实现也会有其不同的特点。MPICH是影响最大、用户最多的MPI实现。眼下可下载的最新的MPICH软件包为MPICH1.2.7pl2008215日公布的MPICH 2-1.0.7測试版(我使用的是MPICH 2-1.0.6pl),在http://www.mcs.anl.gov/research/projects/mpich2/index.php能够下载到,分别有支持UNIXWindows32位和64位版本号。

3.1.2 MPI程序的特点

MPI程序是基于消息传递的并行程序。消息传递指的是并行运行的各个进程具有自己独立的堆栈和代码段,作为互不相关的多个程序独立运行,进程之间的信息交互全然通过显示地调用通信函数来完毕。

3.2 MPICH的安装和配置

我使用的MPICH2安装文件是mpich2-1.0.6p1-win32-ia32.msi,在Windows下安装MPICH2比較简单,可是要有Microsoft .NET Framework 2.0的支持。安装基本上仅仅要单击“Next”就可以。在安装过程中会提示输入进程管理器的password,这个password被用来訪问全部的程序,这里使用的password为admin

安装完毕后,安装文件夹下的include子文件夹包括了编程所须要的全部头文件,lib子文件夹包括了对应的程序库,而子文件夹bin则包括了MPIWindows以下必须的执行程序。执行时须要的动态链接库被安装在了Windows系统文件夹中。在Windows平台下能够使用Microsoft Visual Studio来开发MPI程序,以下举例说明。

首先,新建一个Win32控制台项目,然后将MPICH2安装文件夹下的include

图3-1 配置头文件文件夹

 

子文件夹增加到头文件文件夹中。在VS 2005的菜单 工具->选项->项目解决方式->VC++文件夹对话框中增加include子文件夹,如图3-1所看到的。再用同样的方法将MPICH2\lib增加到库文件文件夹中,如图3-2。

 

图3-2 配置库文件文件夹

 

为了避免名字冲突,须要在预编译头文件stdafx.h中增加#inlcude mpi.h语句。如今就能够在主程序文件里编写MPI程序了,MPI的开发环境配置完成。

3.3 在Windows下怎样执行MPI程序

我所进行的MPI程序的开发均是在Windows平台下,使用Visual Studio 2005 + MPIEXEC wrapper 进行的,首先用一个简单的Hello World 程序说明执行环境的配置。

依照上一小节介绍配置好开发环境之后,在VS 2005中新建立一个Win32 控制台项目,并取名MPI1,在MPI1.CPP文件里输入以下的程序。在项目属性的“配置属性”->“常规”项中的“字符集”设置为“未设置”,如图3-3所看到的。

例3_1

int _tmain(int argc, _TCHAR* argv[])

{   int rank, size;

       MPI_Init(&argc, &argv);

       MPI_Comm_rank(MPI_COMM_WORLD, &rank);

       MPI_Comm_size(MPI_COMM_WORLD, &size);

       printf("Hello World from thread %d of %d\n", rank, size);

       MPI_Finalize();

       return 0;

}

这个程序比較简单,在函数MPI_Init()MPI_Finalize()之间是程序并行运行的地方,MPI_Init()MPI_Comm_rank()MPI_Comm_size()MPI_Finalize(),这四个函数是MPI中最重要和最经常使用的函数。以下分别说明:

图3-3 配置项目属性

(1)    MPI_InitMPI_Finalize

MPI_Init用来初始化MPI运行环境,建立多个MPI进程之间的联系,为兴许通信做准备。而MPI_Finalize则是结束MPI运行环境。这两个函数就是定义MPI程序的并行区的,除了检測是否初始化的函数之外,不应该在这两个函数定义的区域外调用其他MPI函数。这两个函数都返回整型值,标识函数是否调用成功。

(2)    MPI_Comm_rank

MPI_Comm_rank函数就是用来标识各个MPI进程的,给出调用该函数的进程的进程号。MPI_Comm_rank返回整型的错误值,须要提供两个參数:

l        MPI_Comm类型的通信域,标识參与计算的MPI进程组。上面样例中使用的是MPI_COMM_WORLD,这个进程组是MPI实现预先定义好的进程组,指的是全部MPI进程所在的进程组。假设想要申请自己的特殊的进程组,则须要通过MPI_Comm定义并通过其他MPI函数生成。

l        &rank返回调用进程中的标识号。

MPI还定义了还有一个进程组MPI_COMM_SELF,仅仅包括各个进程自己的进程组。

(3)    MPI_Comm_size

这个函数则用来标识对应进程组中有多少个进程,它也有两个參数:

l        MPI_Comm类型的通信域,标识參与计算的MPI进程组。上面的样例中用的是MPI_COMM_WORLD

l        &size返回对应进程组中的进程数。

执行这个程序,执行结果如图3-4,依照并行执行的方式,上面程序执行结果应该打印两行文字信息,为:

Hello World from thread 0 of 2

Hello World from thread 1 of 2

 

图 3-4 例3_1在windows上的执行结果

(本机系统环境变量OMP_NUM_THREADS值是2),可是执行结果确仅仅打印了一行,显然函数MPI_InitMPI_Finalize之间的代码仅被一个线程串行执行了。经过查询资料知道,MPI程序若要被正确执行须要使用MPICH2安装文件夹下的执行工具MPIEXEC wrapper执行用VS 2005生成的exe文件。启动这个程序,程序的界面如图3-5

 

图 3-5 MPIEXEC wrapper程序界面

因为该程序仅仅有操作系统的管理员才有权使用,所以在第一次执行时须要输入计算机username和口令,而且不同意口令为空,如图3-6。输入完毕后,单击“Register”button完毕注冊,之后就能够使用该工具执行MPI程序了。

“Application”栏中选择要执行的exe程序,在“Number of process”栏中选择要执行程序的线程数,然后单击“Execute”button执行程序。如用4线程执行上面的演示样例程序,输出结果如图3-7所看到的。

 

             图 3-6 输入系统username和口令

 

图 3-7 使用MPIEXEC wrapper执行例3_1的结果

 

4线程分别运行MPI_InitMPI_Finalize之间的代码,打印4行信息,程序运行结果正确。

3.4 MPI的点对点通信

点对点通信是MPI程序的基础,MPI_SendMPI_Recv是两个最重要的函数。这两个函数的标准形式是:

l        int MPI_Send(buf, counter, datatype, dest, tag, comm)

參数作用例如以下:

    buf:发送缓冲区的起始地址,能够是数组或结构指针

    count:非负整数,发送的数据个数

    datatype:发送数据的数据类型

    dest:整型,目的的进程号

    tag:整型,消息标志

    commMPI进程组所在的通信域

这个函数返回整型的错误码,它的含义是向通信域中的dest进程发送数据,数据存放在buf中,类型是datatype,个数是count,这个消息的标志是tag,用以和本进程向同一目的进程发送的其他消息差别开来。

l        int MPI_Recv(buf, count, datatype, source, tag, comm, status)

參数作用例如以下:

    buf:接收缓冲区的起始地址,能够是数组或结构指针

    count:非负整数,最多可接收的数据个数

    datatype:接收数据的数据类型

    source:整型,接收数据的来源,即发送数据进程的进程号

    tag:整型,消息标识,应与发送操作的消息标识同样

    comm:消息接收进程所在的通信域

    statusMPI_Status结构指针,返回状态信息

这个函数返回整型的错误码,它的含义是进程从comm域中source进程接收标签号为tag的数据,并保存到buf中。接收缓冲区buf的大小不能小于发送过来的消息的长度。否则会因为数组越界导致程序出错。參数statusMPI_Status类型的,status主要显示接收函数的各种错误状态。通过訪问status.MPI_SOURCEstatus.MPI_TAGstatus.MPI_ERROR就能够得到发送数据的进程号、使用的标签以及接收操作的错误代码。另外,还能够使用函数MPI_Get_count来获得实际接收到的数据项数。MPI_Get_count的标准定义为:int MPI_Get_count(MPI_Status *status, MPI_Datatype datatype, int *count);将实际接收到数据项数存放到count中。以下用一个程序说明上面提到的函数的用法。

演示样例程序见例3_2

程序的执行结果如图3-8(4个进程)

函数MPI_Get_processor_name用于获得计算机名,并存放在processor_name中,长度为namelen,宏定义MPI_MAX_PROCESSOR_NAME是机器名的最大长度。这个程序的完毕的任务是使进程i发送数据给进程i+1,并等待由进程i-1发送来的数据。最后一个进程则发送数据给进程0。

3.5统计时间函数

为了验证程序并行化后的效果,MPI提供了两个用于统计时间的函数 MPI_WtimeMPI_Wtick。当中MPI_Wtime返回一个双精度数,表示从过去某点的时刻到当前时刻所消耗的时间秒数。而函数MPI_Wtick则返回MPI_Wtime结果的精度。改动例3_2程序,在并行代码两端增加统计时间的函数,如例3_3:

例 3_3(完整程序见演示样例程序4_3)

       begin = MPI_Wtime();

       end = MPI_Wtime();

       diff = end - begin;

       printf("%d process time is %9.7f\n", myid, diff);

       printf("%d process tick is %9.7f\n", myid, MPI_Wtick());

}

执行结果如图3-9:

 

 

图 3-8 例3_2的执行结果

 

 

图 3-9 例3_3的执行结果

3.6负载均衡对程序性能的影响

在并行计算中,假设各个处理器上的工作所须要的完毕时间不同,则会使先完毕工作的处理器等待未完毕工作的处理器,浪费了计算资源。这时应该使各个处理器的负载尽量均衡。一般採用的策略有两种:静态负载平衡和动态负载平衡。前者适用于计算前能够准确知道负载,并且这些负载easy平均划分给各个进程的情况。而对于事先不知道负载情况,或者总负载不易划分的情况,则须要採用动态负载划分来解决。在动态负载平衡模式中存在一个管理结点负责给各个进程分配任务,当一个进程完毕当前的计算任务后,它就向管理结点申请新的任务,假设还有未分配的任务,管理结点就将任务分配给那个进程,这有点类似于计算机硬件向CPU发中断请求服务的方式。

3.7 开发实例

以下将在Windows平台上使用MPI编写一个用数值积分法计算圆周率的程序。利用公式PI

的近似值计算圆周率[7],定积分的计算能够转化为求一个曲边梯形的面积问题。将积分区间等分成n个小的子区间,可将每一个小的子区间上的曲边梯形近似地看成矩形,这些矩形面积的和就近似地等于原来曲边梯形的面积。这样终于将求圆周率的问题转化成了一个面积迭加的计算。每一个小矩形的宽为

 

(n为将积分区间等分的份数),高能够将x值带入函数

 

求得。用循环将每一个小矩形的面积累加起来便是PI的近似值。详细的算法实现见附加中的程序“mpi_pi”。图3-103-11各自是用一个进程和两个进程执行的结果。

 

3-10 使用一个进程的执行结果

3-11 使用两个进程的执行结果

从执行结果能够看到使用两个进程时的计算速度反而不如用一个进程执行时的速度,这时因为本程序的计算规模不大,另外引入一个进程的开销大于程序并行所带来的益处,所以进程数越多反而程序的执行速度越慢。看以下一组数据[8](3-1)

计算机数

计算时间

1

1.63643

2

0.83180

3

0.55622

这组数据是在不同的硬件平台下实现本开发实例程序的计算时间。执行环境为台计算机组成的集群配置均为CPU : Intel PentiumIII 733MHz,同样的算法,随着參与计算的机器数添加,计算时间降低。

MPI是针对分布式计算机系统提出的,它採用非共

3-1                享内存的方式利用多进程完毕并行任务,当计算规模不大或处理器数量不多时,很多其它进程的维护会添加系统的开销,并且进程之间的通信存在延时。它比較适合集群计算机系统。

3.8 小结

本章对MPI编程进行了初步研究,介绍了MPI程序的特点、软件包的安装、MPI程序的执行方式。

MPI是一种基于消息传递的并行编程技术,而不是一种详细的编程语言。MPI程序与OpenMP程序的最大不同就是MPI程序不仅能够适用多线程的方式并行运算还能够让程序以多进程的方式运行,以这样的方式运行的程序并不共享内存,各个进程是通过消息传递来进行通信的。这样做的优点是完毕某一计算任务的不同进程能够运行在不同处理器上(不仅仅是处理器的不同核上),甚至是不同的结点计算机上,方便分布式计算系统的构建。在多核上使用MPI能够採用两种方式,一种是在多核平台上开发传统的多进程MPI并行程序,一个核运行一个MPI进程。第二种方式是採用MPI + OpenMP的方法,在结点内採用多线程方式,结点间採用MPI多进程方式。


转自:http://blog.csdn.net/gexplore/article/details/7078832


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/546025.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

最简单的6种防止数据重复提交的方法!(干货)

有位朋友,某天突然问磊哥:在 Java 中,防止重复提交最简单的方案是什么?这句话中包含了两个关键信息,第一:防止重复提交;第二:最简单。于是磊哥问他,是单机环境还是分布式…

漫画:如何证明sleep不释放锁,而wait释放锁?

wait 加锁示例public class WaitDemo {private static Object locker new Object();public static void main(String[] args) throws InterruptedException {WaitDemo waitDemo new WaitDemo();// 启动新线程,防止主线程被休眠new Thread(() -> {try {waitDemo…

设计模式 之 建造者

建造者模式(Builder Pattern) 一听这个名字,你可能就会猜到一二分了。建造者简单理解就是造东西,仅仅只是建造者模式建造的不是一个简单的东西,是一个比較复杂的东西。就好像盖房子,须要打地基、砌墙、灌…

支付宝上市,让我损失了2000万(盘点这些年错过的机会)

选择大于努力!这句话在之前,我只是用排除法来解释它(如果你的选择是错的,那么走的越快就离目标越远),而如今几次亲身的经历,却给了我不同的答案...近几天支付宝上市的事儿,传的沸沸扬…

(转)深入理解最强桌面地图控件GMAP.NET --- 原理篇

前几篇介绍了一些国内地图的案例, 深入理解最强桌面地图控件GMAP.NET --- SOSO地图 深入理解最强桌面地图控件GMAP.NET --- 百度地图 我们以Google地图为例,这章介绍下地图加载的原理。 投影(Projection) 谷歌地图采用的是墨卡托投影法,这里转载(http://…

LeetCode刷题--- 字母大小写全排列

个人主页:元清加油_【C】,【C语言】,【数据结构与算法】-CSDN博客 个人专栏 力扣递归算法题 http://t.csdnimg.cn/yUl2I 【C】 http://t.csdnimg.cn/6AbpV 数据结构与算法 http://t.csdnimg.cn/hKh2l 前言:这个专栏主要讲述递归递归、搜索与回…

4种分布式Session的实现方式!老大直呼666...

前言公司有一个 Web 管理系统,使用 Tomcat 进行部署。由于是后台管理系统,所有的网页都需要登录授权之后才能进行相应的操作。起初这个系统的用的人也不多,为了节省资源,这个系统仅仅只是单机部署。后来随着用的人越来越多&#x…

回溯算法n皇后问题_使用回溯算法的N Queen问题和解决方案

回溯算法n皇后问题N-皇后问题 (N - Queens problem) The n – queen problem is the generalized problem of 8-queens or 4 – queen’s problem. Here, the n – queens are placed on a n * n chess board, which means that the chessboard has n rows and n columns and t…

超简单的分布式ID生成方案!美团开源框架介绍

目录阐述背景Leaf snowflake 模式介绍Leaf segment 模式介绍Leaf 改造支持 RPC阐述背景不吹嘘,不夸张,项目中用到 ID 生成的场景确实挺多。比如业务要做幂等的时候,如果没有合适的业务字段去做唯一标识,那就需要单独生成一个唯一的…

教你写Bug,常见的 OOM 异常分析

在《Java虚拟机规范》的规定里,除了程序计数器外,虚拟机内存的其他几个运行时区域都有发生 OutOfMemoryError 异常的可能。本篇主要包括如下 OOM 的介绍和示例:java.lang.StackOverflowErrorjava.lang.OutOfMemoryError: Java heap spacejava…

池化技术到达有多牛?看了线程和线程池的对比吓我一跳!

这是我的第 82 篇原创文章作者 | 王磊来源 | Java中文社群(ID:javacn666)转载请联系授权(微信ID:GG_Stone)情商高的人是能洞察并照顾到身边所有人的情绪,而好的文章应该让所有人都能看懂。尼采曾…

spearman相关性_Spearman的相关性及其在机器学习中的意义

spearman相关性This article is about correlation and its implication in the machine learning. In my previous article, I have discussed Pearson’s correlation coefficient and later we have written a code to show the usefulness of finding Pearson’s correlati…

被问哭了,一位小姐姐的阿里面经!(附部分答案)

这篇文章是一位 女读者 (加粗!太难得)的面试阿里的经历分享,虽然第二面就失败了,但是这样的经历对自己帮助应该还是很大的。下面的一些问题非常具有代表性,部分问题我简单做了修改(有些问题表述…

阿里《Java开发手册》最新嵩山版发布!

《Java 开发手册》是阿里巴巴集团技术团队的集体智慧结晶和经验总结,经历了多次大规模一线实战的检验及不断完善,公开到业界后,众多社区开发者踊跃参与,共同打磨完善,系统化地整理成册,当前的版本是嵩山版。…

递归转化成非递归过程_8086微处理器中的递归和重入过程

递归转化成非递归过程As we all know that a procedure is a set of instruction written separately which can be used any time in the code when required. A normal procedure execution includes calling of the procedure, shifting the control of the processor to th…

漫谈软件研发特种部队之中的一个

特种部队,是指进行特殊任务的部队,具有编制灵活、人员精干、装备精良、机动高速、训练有素、战斗力强等特点。 特种部队最早出如今二战期间。德国于1939年9月1日的波兰战役中首次投入了一种被称为“勃兰登堡”部队的特种部队作为德国突击波兰的先锋&…

不要一把梭了,这才是SQL优化的正确姿势!|原创干货

这是我的第 83 篇原创文章作者 | 王磊来源 | Java中文社群(ID:javacn666)转载请联系授权(微信ID:GG_Stone)年少不知优化苦,遇坑方知优化难。——村口王大爷全文内容预览:我之前有很多…

PLSQL_性能优化系列10_Oracle Array数据组优化

2014-09-25 Created By BaoXinjian 一、摘要 集合是Oracle开发中经常遇到的情况,Oracle集合分为三种情况:索引表集合(index by table)、嵌套表集合(nested table)、可变集合(varry table)。 PL/SQL中没有数组的概念,他的集合数据类型和数组是…

IDEA 2020.2 重磅发布,动画级新功能预览!

Guide 关注了 IDEA 的官推,平时没事就会去看看有没有啥比较好的更新。今天下午看到IntelliJ IDEA 2020.2 都已经发布并且还支持了 Java15。然后,我就去官网简单看了一下新特性。单看新特性,这个新版本还是有一点香的。虽然我还木有升级到这个…

访问控制模型ACL和RBAC

2019独角兽企业重金招聘Python工程师标准>>> 1.ACL ACL是最早也是最基本的一种访问控制机制,它的原理非常简单:每一项资源,都配有一个列表,这个列表记录的就是哪些用户可以对这项资源执行CRUD中的那些操作。当系统试图…