完整word版MPI并行编程实验报告.docx

上传人:b****4 文档编号:4029113 上传时间:2022-11-27 格式:DOCX 页数:28 大小:132.03KB
下载 相关 举报
完整word版MPI并行编程实验报告.docx_第1页
第1页 / 共28页
完整word版MPI并行编程实验报告.docx_第2页
第2页 / 共28页
完整word版MPI并行编程实验报告.docx_第3页
第3页 / 共28页
完整word版MPI并行编程实验报告.docx_第4页
第4页 / 共28页
完整word版MPI并行编程实验报告.docx_第5页
第5页 / 共28页
点击查看更多>>
下载资源
资源描述

完整word版MPI并行编程实验报告.docx

《完整word版MPI并行编程实验报告.docx》由会员分享,可在线阅读,更多相关《完整word版MPI并行编程实验报告.docx(28页珍藏版)》请在冰豆网上搜索。

完整word版MPI并行编程实验报告.docx

完整word版MPI并行编程实验报告

姓名

学号

实验

成绩

 

计算机系统结构

实验报告

 

课题:

MPI并行编程实验

起讫日期:

2012-05-20~2012-06-15

组名:

第四组

院系:

计算机学院

专业:

计算机科学与技术

指导老师:

XXX教授

 

2012年6月15日

实验一Linux下基于MPI的hello程序设计

Author:

姓名

一、MPICH并行计算库安装

在Linux环境下安装MPICH执行环境,配置MPD.CONF,完成实验室中临近机器间的并行配置。

概要:

以寝室四台计算机为例,设置IP(192.168.1.1~192.168.1.4),更改主机名为node01,node02,node03,node04。

(一)创建SSH信任连接

1、更改/etc/hosts文件

#vi/etc/hosts打开hosts文件,更改如下:

127.0.0.1localhost.localdomainlocalhost

192.168.1.1node01

192.168.1.2node02

192.168.1.3node03

192.168.1.4node04

2、在node01生成SSH秘钥对.

#ssh-keygen-trsa一路回车即可

产生.ssh文件,

#ls-a查看是否有.ssh文件夹

3、进入.ssh目录

#cd.ssh

4、生成authorized_keys文件

#cpid_rsa.pubauthorized_keys

5、退出到root目录

#cd..

6、建立本身的信任连接

#sshnode01按提示输入yes(三个字母要打全)

7、设置node02(node02的root目录下)

#ssh-keygen-trsa生成.ssh文件夹

#scpnode01的IP:

/root/.ssh/*/root/.ssh拷贝node01上的.ssh文件夹覆盖本地的

#scpnode01的IP:

/etc/hosts/etc/hosts拷贝node01上的hosts文件覆盖本地的

#sshnode01提示处输入yes回车

设置node03,node04的方法与node02相同

8、确认四台机器的信任连接已建立

对每个节点执行:

#sshnode01

#sshnode02

#sshnode03

#sshnode04

在提示处输入yes回车,最后确定无需输入密码并且没有任何提示信息即可登陆("Lastlogin:

时间日期"提示信息除外)

(二)安装MPICH2

1、解压缩文件包

#tar-zxvfmpich2-1.0.1.tar.gz

2、创建安装目录

#mkdir/usr/MPICH-instsll

3、进入mpich2解压目录

#cdmpich2-1.0.1

4、设置安装目录

#./configure--prefix=/usr/MPICH-install

5、编译

#make

6、安装

#makeinstall

7、退出到root目录

#cd..

8、通过编辑.bashrc文件修改环境变量

#vi.bashrc

修改后的.bashrc文件如下:

#.bashrc

#Userspecificaliasesandfunctions

aliasrm='rm-i'

aliascp='cp-i'

aliasmv='mv-i'

PATH="$PATH:

/usr/MPICH-install/bin"新增加的

#Sourceglobaldefinitions

if[-f/etc/bashrc];then

./etc/bashrc

fi

9、测试环境变量设置

#source~/.bashrc

#whichmpd

#whichmpicc

#whichmpiexec

#whichmpirun

10、修改/etc/mpd.conf文件,内容为secretword=myword

#vi/etc/mpd.conf

设置文件读取权限和修改时间

#touch/etc/mpd.conf

#chmod600/etc/mpd.conf

11、创建主机名称集合文件/root/mpd.hosts

#vimpd.hosts

文件内容如下:

node01

node02

node03

node04

(三)配置NFS

为了方便MPICH的安装及并行程序的运行,最好将MPICH的安装目录及用户家目录通过NFS网络文件系统共享。

对于仅包含几个结点的较小的集群系统,可以任意指定其中一个结点作为NFS服务器。

对较大的集群系统,应设定一个或数个结点专门用于文件服务,这些结点称为I/O结点,它们专门负责存储设备的管理,不参加计算。

这里选择node1作为NFS服务器,将它的/home和/usr/MPICH-nstall目录输出给其他三个结点,相应的配置步骤如下。

1、以root身分登录到node1上,确保node1上安装了NFS程序(nfs-utils包)。

首先运行一遍下述命令来开启NFS服务:

/sbin/chkconfignfson

/sbin/chkconfignfslockon

/etc/init.d/nfslockrestart

/etc/init.d/nfsrestart

然后编辑文件/etc/exports,在其中加入下面二行(如果该文件不存在则创建一个新文件):

/home10.0.0.0/255.255.255.248(rw,async,no_root_squash)

/usr/MPICH-install10.0.0.0/255.255.255.248(rw,async,no_root_squash)

做好上述修改后执行下面的命令:

/sbin/exportfs-a

便完成了/home和/usr/local目录的输出。

2、以root身份登录到其余三个结点,在文件/etc/fstab中加入下面两行:

node1:

/home/homenfsdefaults00

node1:

/usr/local/usr/localnfsdefaults00

并且运行一次下述命令:

/sbin/chkconfignetfson

mount-tnfs-a

完成上面的步骤后,node2,node3和node4应该共享node1的/home和/usr/MPICH-install目录。

可以在任何一个结点上用df命令来验证,例如:

#df

返回类似下面所示的结果:

......

node1:

/home2486326442240284841197428095%/home

node1:

/usr/MPICH-install2469668882008885603353307686%/usr/local

(四)环境测试

1、本地测试

#mpd&启动

#mpdtrace观看启动机器

#mpdallexit退出

2、通过mpd.hosts运行集群系统

#mpdboot-nnumber-fmpd.hostsnumber为要起动的机器个数

#mpdtrace

#mpdallexit

3、测试运行MPICH的例子程序

#mpdboot-n4-fmpd.hosts启动4台机器

#mpiexec-nnumber/usr/MPICH-install/examples/cpinumber为使用的进程数

#mpdallexit

二.HELLOWORLD并行程序设计

(一)程序源码:

/*hello.c*/

#include

#include"mpi.h"

intmain(intargc,char*argv[])

{

intrank;

intsize;

MPI_Init(0,0);

MPI_Comm_rank(MPI_COMM_WORLD,&rank);

MPI_Comm_size(MPI_COMM_WORLD,&size);

printf("Helloworldfromprocess%dof%d\n",rank,size);

MPI_Finalize();

return0;

}

(二)程序编译

$mpicc–ohellohello.c

(三)运行结果

$mpdboot–n-fmpd.hosts

$mpiexec–n./hello

(四)实验心得:

基本上和vc运行是一样的,只是环境不一样,编译时要用mpicc–ohellohello.c运行时要用mpiexec–n./hello,错误多错几次口令也就背下来了,当让,在运行框里可以看出我刚开始忘了建自己的目录就想开始编辑程序。

实验二对等模式的MPI程序设计

Author:

姓名

一、实验目的:

掌握MPI并行程序设计的基本思想和主要编程方法,编写一个具有对等模式的MPI程序,实现各进程的对等。

二、基本概念:

所谓对等模式,就是说MPI程序的各个进程的功能、地位相同或相近,MPI程序的代码也应该是相近的,所不同的只是处理的对象和操作的数据,比如MPI程序让各个进程同时对一个数组的不同部分并行赋初值,各个进程间的关系就是典型的对等关系。

三、实验环境:

MPICH2

Windows7

四、模块说明:

Jacobi叠代

为了并行求解,这里将参加迭代的数据按列进行分割,并假设一共有4个进程同时并行计算,数据的分割结果如下图所示。

Jacobi迭代的数据划分及其与相应进程的对应

 

捆绑发送接收

捆绑发送和接收操作把发送一个消息到一个目的地和从另一个进程接收一个消息合并到一个调用中,源和目的可以是相同的。

捆绑发送接收操作虽然在语义上等同于一个发送操作和一个接收操作的结合,但是它可以有效地避免由于单独书写发送或接收操作时,由于次序的错误而造成的死锁。

这是因为该操作由通信系统来实现,系统会优化通信次序,从而有效地避免不合理的通信次序,最大限度避免死锁的产生。

  捆绑发送接收操作是不对称的,即一个由捆绑发送接收调用发出的消息可以被一个普通接收操作接收,一个捆绑发送接收调用可以接收一个普通发送操作发送的消息。

  该操作执行一个阻塞的发送和接收,接收和发送使用同一个通信域,但是可能使用不同的标识。

发送缓冲区和接收缓冲区必须分开,他们可以是不同的数据长度和不同的数据类型。

虚拟进程

  虚拟进程(MPI_PROC_NULL)是不存在的假想进程,在MPI中的主要作用是充当真实进程通信的目或源,引入虚拟进程的目的是为了在某些情况下编写通信语句的方便。

当一个真实进程向一个虚拟进程发送数据或从一个虚拟进程接收数据时,该真实进程会立即正确返回,如同执行了一个空操作。

  在很多情况下为通信指定一个虚拟的源或目标是非常方便的,这不仅可以大大简化处理边界的代码,而且使程序显得简洁易懂。

在捆绑发送接收操作中经常用到这种通信手段。

一个真实进程向虚拟进程MPI_PROC_NULL发送消息时会立即成功返回;一个真实进程从虚拟进程MPI_PROC_NULL的接收消息时也会立即成功返回,并且对接收缓冲区没有任何改变。

五、程序设计:

Jacobi叠代的实现

  programmain

  implicitnone

  include'mpif.h'

  integertotalsize,mysize,steps

  parameter(totalsize=16)

C定义全局数组的规模

  parameter(mysize=totalsize/4,steps=10)

  integern,myid,numprocs,i,j,rc

  reala(totalsize,mysize+2),b(totalsize,mysize+2)

C定义局部数组

  integerbegin_col,end_col,ierr

  integerstatus(MPI_STATUS_SIZE)

  callMPI_INIT(ierr)

  callMPI_COMM_RANK(MPI_COMM_WORLD,myid,ierr)

  callMPI_COMM_SIZE(MPI_COMM_WORLD,numprocs,ierr)

  print*,"Process",myid,"of",numprocs,"isalive"

C数组初始化

  doj=1,mysize+2

   doi=1,totalsize

    a(i,j)=0.0

   enddo

  enddo

  if(myid.eq.0)then

   doi=1,totalsize

    a(i,2)=8.0

   enddo

  endif

  if(myid.eq.3)then

   doi=1,totalsize

    a(i,mysize+1)=8.0

   enddo

  endif

  doi=1,mysize+2

   a(1,i)=8.0

   a(totalsize,i)=8.0

  enddo

CJacobi迭代部分

  don=1,steps

C从右侧的邻居得到数据

  if(myid.lt.3)then

   callMPI_RECV(a(1,mysize+2),totalsize,MPI_REAL,myid+1,10,

*    MPI_COMM_WORLD,status,ierr)

  endif

C向左侧的邻居发送数据

  if((myid.gt.0))then

   callMPI_SEND(a(1,2),totalsize,MPI_REAL,myid-1,10,

*   MPI_COMM_WORLD,ierr)

  endif

C向右侧的邻居发送数据

  if(myid.lt.3)then

   callMPI_SEND(a(1,mysize+1),totalsize,MPI_REAL,myid+1,10,

*   MPI_COMM_WORLD,ierr)

  endif

C从左侧的邻居接收数据

  if(myid.gt.0)then

   callMPI_RECV(a(1,1),totalsize,MPI_REAL,myid-1,10,

*   MPI_COMM_WORLD,status,ierr)

  endif

  begin_col=2

  end_col=mysize+1

  if(myid.eq.0)then

   begin_col=3

  endif

  if(myid.eq.3)then

   end_col=mysize

  endif

  doj=begin_col,end_col

   doi=2,totalsize-1

    b(i,j)=(a(i,j+1)+a(i,j-1)+a(i+1,j)+a(i-1,j))*0.25

   enddo

  enddo

  doj=begin_col,end_col

   doi=2,totalsize-1

    a(i,j)=b(i,j)

   enddo

  enddo

  enddo

  doi=2,totalsize-1

   print*,myid,(a(i,j),j=begin_col,end_col)

  enddo

  callMPI_Finalize(rc)

  end

捆绑发送接收

MPI_SENDRECV(sendbuf,sendcount,sendtype,dest,sendtag,recvbuf,recvcount,

recvtype,source,recvtag,comm,status)

 

INsendbuf

INsendcount

INsendtype

INdest

INsendtag

OUTrecvbuf

INrecvcount

INrecvtype

INsource

INrecvtag

INcomm

OUTstatus

发送缓冲区起始地址(可选数据类型)

发送数据的个数(整型)

发送数据的数据类型(句柄)

目标进程标识(整型)

发送消息标识(整型)

接收缓冲区初始地址(可选数据类型)

最大接收数据个数(整型)

接收数据的数据类型(句柄)

源进程标识(整型)

接收消息标识(整型)

通信域(句柄)

返回的状态(status)

intMPI_Sendrecv(void*sendbuf,intsendcount,MPI_Datatypesendtype,intdest,

  intsendtag,void*recvbuf,intrecvcount,MPI_Datatyperecvtype,intsource,

  intrecvtag,MPI_Commcomm,MPI_Status*status)

MPI_SENDRECV(SENDBUF,SENDCOUNT,SENDTYPE,DEST,SENDTAG,

  RECVBUF,RECVCOUNT,RECVTYPE,SOURCE,RECVTAG,COMM,

  STATUS,IERROR)

  SENDBUF(*),RECVBUF(*)

INTEGERSENDCOUNT,SENDTYPE,DEST,SENDTAG,RECVCOUNT,

RECVTYPE,SOURCE,RECVTAG,COMM,STATUS(MPI_STATUS_SIZE),IERROR

虚拟进程

 programmain

 implicitnone

 include'mpif.h'

 integertotalsize,mysize,steps

 parameter(totalsize=16)

 parameter(mysize=totalsize/4,steps=10)

 integern,myid,numprocs,i,j,rc

 reala(totalsize,mysize+2),b(totalsize,mysize+2)

 integerbegin_col,end_col,ierr

 integerleft,right,tag1,tag2

 integerstatus(MPI_STATUS_SIZE)

 callMPI_INIT(ierr)

 callMPI_COMM_RANK(MPI_COMM_WORLD,myid,ierr)

 callMPI_COMM_SIZE(MPI_COMM_WORLD,numprocs,ierr)

 print*,"Process",myid,"of",numprocs,"isalive"

C数组初始化

  doj=1,mysize+2

   doi=1,totalsize

    a(i,j)=0.0

   enddo

  enddo

  if(myid.eq.0)then

   doi=1,totalsize

    a(i,2)=8.0

   enddo

  endif

  if(myid.eq.3)then

   doi=1,totalsize

    a(i,mysize+1)=8.0

   enddo

  endif

  doi=1,mysize+2

   a(1,i)=8.0

   a(totalsize,i)=8.0

  enddo

  tag1=3

  tag2=4

C设置当前进程左右两侧的进程标识

  if(myid.gt.0)then

   left=myid-1

  else

   left=MPI_PROC_NULL

  endif

  if(myid.lt.3)then

   right=myid+1

  else

   right=MPI_PROC_NULL

  endif

CJacobi迭代

  don=1,steps

C从左向右平移数据

  callMPI_SENDRECV(a(1,mysize+1),totalsize,MPI_REAL,right,tag1,

*      a(1,1),totalsize,MPI_REAL,left,tag1,

*      MPI_COMM_WORLD,status,ierr)

C从右向左平移数据

  callMPI_SENDRECV(a(1,2),totalsize,MPI_REAL,left,tag2,

*      a(1,mysize+2),totalsize,MPI_REAL,right,tag2,

*      MPI_COMM_WORLD,status,ierr)

  begin_col=2

  end_col=mysize+1

  if(myid.eq.0)then

   begin_col=3

  endif

  if(myid.eq.3)then

   end_col=mysize

  endif

  doj=begin_col,end_col

   doi=2,totalsize-1

    b(i,j)=(a(i,j+1)+a(i,j-1)+a(i+1,j)+a(i-1,j))*0.25

   enddo

  enddo

  doj=begin_col,end_col

   doi=2,totalsize-1

    a(i,j)=b(i,j)

   enddo

  enddo

  enddo

  doi=2,totalsize-1

   print*,myid,(a(i,j),j=begin_col,end_col)

  enddo

   callMPI_Finalize(rc)

  end

实验三基于MPI计算π值

Author:

姓名

一、实验题目

用MPI技术计算π的值。

二、实验目的

熟悉MPI编程,加深对其编程的理解。

三、实验环境

WindowsXPSP3。

运行MPI

(一)安装MPI

第一步:

下载MPI软件包

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1