MPICH2在Windows环境下Visual_Studio_2010的环境搭建.docx_第1页
MPICH2在Windows环境下Visual_Studio_2010的环境搭建.docx_第2页
MPICH2在Windows环境下Visual_Studio_2010的环境搭建.docx_第3页
MPICH2在Windows环境下Visual_Studio_2010的环境搭建.docx_第4页
MPICH2在Windows环境下Visual_Studio_2010的环境搭建.docx_第5页
已阅读5页,还剩13页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

MPICH2在Windows系统Visual Studio 2010的环境搭建本机运行环境:机器型号:联想G450处理器:Pentium(R)Dual-Core CPU T4200 2.00GHz 运行内存(RAM):2GB操作系统: Windows 7(32位)程序开发环境:Visual Studio 2008MPI版本:mpich2-1.3.2p1-win-ia32安装程序MPI的编译和运行对于简单的程序,可以使用专门的编译命令。对于大的项目,最好使用标准的Makefile。MPICH提供的编译命令有mpicc和mpif77,它们分别是C和Fortran的编译命令:mpicc -o first first.c mpif77 -o first firstf.f 对于编译得到的目标程序,运行的命令为:mpirun arch xxx np yyy first其中xxx为machines.的,yyy为申请的进程数目。MPICH的安装和配置文中使用的MPICH2安装文件是mpich2-1.4-win-ia32 (/mpi/mpich),在Windows下安装MPICH2比较简单,但是要有Microsoft .NET Framework的支持。安装基本上只要单击“Next”即可。在安装过程中会提示输入进程管理器的密码,这个密码被用来访问所有的程序,这里使用的密码为admin。如果是多台机器执行mpi,那么这多台机器上必须配置相同的mpi用户,就是新用户的用户名和密码必须相同。安装完成后,安装目录下的include子目录包含了编程所需要的所有头文件,lib子目录包含了相应的程序库,而子目录bin则包含了MPI在Windows下面必须的运行程序。运行时需要的动态链接库被安装在了Windows系统目录中。在Windows平台下可以使用Microsoft Visual Studio来开发MPI程序。首先,下载mpich2,并进行安装。本机的安装路径为:C:Program FilesMPICH2。之后配置系统环境变量,计算机-属性-高级-环境变量-Path,如下图:在系统中新创建一个用户,计算机-管理-右键用户-新用户,如下图:ID:zhang Password:zhang运行wmpiregister.exe,配置mpi使用这个新创建的用户,点击填入用户名和密码,然后点击register,如下图:用win32控制台应用程序新建一个MYMPI项目,将MPICH2安装目录下的include子目录加入到头文件目录中。在MYMPI项目属性配置属性VC+目录对话框中添加include子目录,如下图:再用相同的方法将MPICH2lib加入到库文件目录中,如下图:同样方法,配置程序,连接mpi库,如下图:为了避免名字冲突,需要在预编译头文件stdafx.h中加入#inlcude mpi.h语句。现在就可以在主程序文件中编写MPI程序了,MPI的开发环境配置完毕。在Windows下运行MPI程序按照上面配置好开发环境之后,在MY MPI.CPP文件中输入下面的程序。在项目属性的“配置属性”“常规”项中的“字符集”设置为“未设置”。程序参数说明一般的 MPI 程序设计流程图:进入MPI 系统,通信器 MPI_COMM_WORLD 形成Call MPI Init ( )Call MPI_Comm_rank ( )Call MPI_Comm_size ( )建立新的通信器、定义新的数据类型和进程拓扑结构应用程序实体: 1计算控制程序体; 2进程间通信;退出 MPI 系统Call MPI_Finalize ( )End然后编写测试程序:#includestdafx.h#includempi.h#includeusingstd:cout;usingstd:endl;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 %dn, rank, size);MPI_Finalize();return 0;这个程序比较简单,在函数MPI_Init()和MPI_Finalize()之间是程序并行执行的地方,MPI_Init()、MPI_Comm_rank()、MPI_Comm_size()和MPI_Finalize(),这四个函数是MPI中最重要和最常用的函数。下面分别说明:(1)MPI_Init和MPI_FinalizeMPI_Init用来初始化MPI执行环境,建立多个MPI进程之间的联系,为后续通信做准备。而MPI_Finalize则是结束MPI执行环境。这两个函数就是定义MPI程序的并行区的,除了检测是否初始化的函数之外,不应该在这两个函数定义的区域外调用其它MPI函数。这两个函数都返回整型值,标识函数是否调用成功。(2)MPI_Comm_rankMPI_Comm_rank函数就是用来标识各个MPI进程的,给出调用该函数的进程的进程号。MPI_Comm_rank返回整型的错误值,需要提供两个参数:MPI_Comm类型的通信域,标识参与计算的MPI进程组。上面例子中使用的是MPI_COMM_WORLD,这个进程组是MPI实现预先定义好的进程组,指的是所有MPI进程所在的进程组。如果想要申请自己的特殊的进程组,则需要通过MPI_Comm定义并通过其它MPI函数生成。&rank返回调用进程中的标识号。MPI还定义了另一个进程组MPI_COMM_SELF,只包含各个进程自己的进程组。(3)MPI_Comm_size这个函数则用来标识相应进程组中有多少个进程,它也有两个参数:MPI_Comm类型的通信域,标识参与计算的MPI进程组。上面的例子中用的是MPI_COMM_WORLD。&size返回相应进程组中的进程数。运行这个程序,运行结果如图3-4,按照并行执行的方式,上面程序运行结果应该打印两行文字信息,为:Hello World from thread 0 of 2Hello World from thread 1 of 2编译运行这个程序,如下图:本机系统环境变量OMP_NUM_THREADS值是2,但是运行结果确只打印了一行,显然函数MPI_Init和MPI_Finalize之间的代码仅被一个线程串行执行了。MPI程序若要被正确运行,需要使用MPICH2安装目录下的运行工具MPIEXEC wrapper运行用VS 2005生成的exe文件。启动这个程序,程序的界面如图在“Application”栏中选择要运行的exe程序,在“Number of process”栏中选择要运行程序的线程数,然后单击“Execute”按钮运行程序。运行上面的示例程序,输出结果如图所示4线程分别执行MPI_Init和MPI_Finalize之间的代码,打印4行信息,程序执行结果正确。MPI的点对点通信有消息传递功能的并行程序,消息传递是MPI编程的核心功能,掌握了MPI消息传递编程方法就掌握了MPI编程的核心。点对点通信是MPI程序的基础,MPI_Send和MPI_Recv是两个最重要的函数。这两个函数的标准形式是:int MPI_Send(buf, counter, datatype, dest, tag, comm)参数作用如下:buf:发送缓冲区的起始地址,可以是数组或结构指针 count:非负整数,发送的数据个数 datatype:发送数据的数据类型 dest:整型,目的的进程号 tag:整型,消息标志 comm:MPI进程组所在的通信域这个函数返回整型的错误码,它的含义是向通信域中的dest进程发送数据,数据存放在buf中,类型是datatype,个数是count,这个消息的标志是tag,用以和本进程向同一目的进程发送的其它消息区别开来。 int MPI_Recv(buf, count, datatype, source, tag, comm, status)参数作用如下: buf:接收缓冲区的起始地址,可以是数组或结构指针 count:非负整数,最多可接收的数据个数 datatype:接收数据的数据类型 source:整型,接收数据的来源,即发送数据进程的进程号 tag:整型,消息标识,应与发送操作的消息标识相同 comm:消息接收进程所在的通信域 status:MPI_Status结构指针,返回状态信息这个函数返回整型的错误码,它的含义是进程从comm域中source进程接收标签号为tag的数据,并保存到buf中。接收缓冲区buf的大小不能小于发送过来的消息的长度。否则会由于数组越界导致程序出错。参数status是MPI_Status类型的,status主要显示接收函数的各种错误状态。通过访问status.MPI_SOURCE、status.MPI_TAG和status.MPI_ERROR就可以得到发送数据的进程号、使用的标签以及接收操作的错误代码。另外,还可以使用函数MPI_Get_count来获得实际接收到的数据项数。MPI_Get_count的标准定义为:int MPI_Get_count(MPI_Status *status, MPI_Datatype datatype, int *count);将实际接收到数据项数存放到count中。下面用一个程序说明上面提到的函数的使用方法。函数MPI_Get_processor_name用于获得计算机名,并存放在processor_name中,长度为namelen,宏定义MPI_MAX_PROCESSOR_NAME是机器名的最大长度。这个程序的完成的任务是使进程i发送数据给进程i+1,并等待由进程i-1发送来的数据。最后一个进程则发送数据给进程0。群体通信群体通信意味着一个通信子中的所有进程调用同一例程,所有的群体操作都是阻塞的,它包括如下一些:同步(barrier)从一个进程到本组内的所有进程的播送(broadcast)(如图 3.3 的(a)从本组所有处理收集数据到一个进程(gather)(如图 3.3 的(b)从一个进程分散数据到本组内的所有进程(sactter)(如图 3.3 的(b)将gather的数据不是送到某一进程,而是要送到所有本组内的进程(allgather) (如图 3.3 的(c)组内的多对多的分散/收集(alltoall)(如图 3.3 的(d)求和,最大值,最小值及用户定义的函数等的reduce操作scan或prefix操作图 3.3 群体操作的图例1、同步int MPI_Barrier(MPI_Comm comm)它使得调用者阻塞,直到该通信子内所有进程都调用它。2、广播int MPI_Bcast(void *buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm);所有进程使用同一计数、数据类型、根和通信子。在操作前,根缓冲区包含一个消息。操作后,所有缓冲区包含来自根进程的消息。3、散播int MPI_Scatter(void *sndbuf, int sndcnt, MPI_Datatype sndtype, void *rcvbuf, int rcvcnt, MPI_Datatype rcvtype, int root, MPI_Comm comm);所有进程使用同一计数、数据类型、根和通信子。在操作前,根发送缓冲区包含长度为sndcnt * N的消息,这里N是进程数目。操作后,相等地划分消息,并且分散到随后标识数序的所有进程(包括根)。4、归约int MPI_Reduce(void *sndbuf, void *rcvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm);所有进程使用同一计数、数据类型、根和通信子。操作后,根进程在它的接受缓冲区中有所有进程的发送缓冲区的归约结果,包括:MPI_MAX, MPI_MIN, MPI_SUM, MPI_PROD, MPI_LAND, MPI_BAND, MPI_LOR, MPI_BOR, MPI_LXOR, MPI_BXOR,或者是用户定义的归约函数。5、收集int MPI_Gather(void *sndbuf, int sndcnt, MPI_Datatype sndtype, void *rcvbuf, int rcvcnt, MPI_Datatype rcvtype, int root, MPI_Comm comm);所有进程使用同一计数、数据类型、根和通信子。此例程是MPI_Scatter()的相反:操作后,根进程在它的接受缓冲区中包含所有进程的发送缓冲区的连接(包括它自己),所有消息长度为rcvcnt * N, 这里N是进程数目。按照随后的标识数序收集消息。6、群体通信的例子下面简单的代码段使用了四个基本的集合例程以操纵一个静态的已划分的规则区域(这里是一维)。全域的长度从根进程广播到所有其它进程。初始数据集在进程间分配(分散)。在每一计算步骤之后,确定全局的最大数并由根所使用。根然后收集最终的数据集。#include int i,myrank,size,root,full_domain_length,sub_domain_length; double global_max,local_max,*full_domain, *sub_domain; MPI_Comm_rank(MPI_COMM_WORLD, &myrank); MPI_Comm_size(MPI_COMM_WORLD, &size); root = 0; if (myrank = root) get_full_domain(&full_domain, &full_domain_length); MPI_Bcast(&full_domain_length, 1, MPI_INT, root, MPI_COMM_WORLD); sub_domain_length = full_domain_length / size; sub_domain = (double *) malloc(sub_domain_length * sizeof(double);MPI_Scatter(full_domain, sub_domain_length, MPI_DOUBLE, sub_domain, sub_domain_length, MPI_DOUBLE, root, MPI_COMM_WORLD); compute(sub_domain, sub_domain_length, &local_max); MPI_Reduce(&local_max, &global_max, 1, MPI_DOUBLE, MPI_MAX, root, MPI_COMM_WORLD);MPI_Gather(sub_domain, sub_domain_length, MPI_DOUBLE, full_domain, sub_domain_length, MPI_DOUBLE, root, MPI_COMM_WORLD);参考第四讲MPI编程及矩阵相乘。Ppt统计时间函数为了验证程序并行化后的效果,MPI提供了两个用于统计时间的函数 MPI_Wtime和 MPI_Wtick。其中MPI_Wtime返回一个双精度数,表示从过去某点的时刻到当前时刻所消耗的时间秒数。而函数MPI_Wtick则返回MPI_Wtime结果的精度。修改例3_2程序,在并行代码两端加入统计时间的函数,如例3_3:例 3_3begin = MPI_Wtime();end = MPI_Wtime();diff = end - begin;printf(%d process time is %9.7fn, myid, diff);

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论