首页 热点资讯 义务教育 高等教育 出国留学 考研考公
您的当前位置:首页正文

并行程序实验报告

2023-07-16 来源:化拓教育网
并行程序设计实验报告

姓名: 学号:

一、实验目的

通过本次试验,了解使用OpenMP编程的基本方法和MPI的编程方法,通过实践实现的基本程序,掌握基本的线程及进程级并行应用开发技术,能够分析并行性能瓶颈及相应优化方法。

二、实验环境

Linux操作系统,mpi库,多核处理器

三、实验设计与实现

(一)MPI并行程序设计

用MPI编写一个greeting程序,编号为0的进程接受其它各进程的“问候”,并在计算机屏幕上显示问候情况。

用MPI编写一个多进程求积分的程序,并通过积分的方法求的值,结果与的25位精确值比较。 (二)多线程程序设计

用Pthreads或OpenMP编写通过积分的方法求的程序。把该程序与相应的MPI程序比较。

用Pthreads或OpenMP编写编写矩阵相乘的程序,观察矩阵增大以及线程个数增减时的情形。

四、实验环境安装

(一)MPI环境安装

1.安装kylin操作系统的虚拟机(用VirtualBox)

2.安装增强功能,使之与windows主机能够文件共享。

3.拷贝mpich-3.0.4.tar.gz到/root/myworkspace/目录下,并解压(tar xzf mpich-3.0.4.tar.gz)

4.下面开始安装

mkdir /root/myworkspace/mpi

./configure --prefix=/root/myworkspace/mpi --disable-f77 --disable-fc

make

make install

5.配置环境变量

打开/root/.bashrc文件,在文件的末尾加上两行:

PATH=$PATH:/root/myworkspace/mpi/bin export PATH

保存退出,然后执行命令

source /root/.bashrc

(二)openMP实验环境安装

Visual Studio中修改:项目->属性->c/c++->语言,将“OpenMP支持”改成“是”:

五、实验结果及分析

(一)MPI并行程序设计

实验一:问候发送与接收

非零号进程将问候的信息发送给0号进程,0号进程依次接收其它进程发送过来的消息并将其输出。结果如下图:

实验二:多进程通过积分求π,并与精确值比较

由公式:

4dx2, 01x1得π的近似值为:

4NfNi1i0.5 N将0到1的区间分成多份,每个进程负责其中几份的积分运算,最后非零进程将结果传至零号进程,由零号进程负责将各个进程的积分结果求和并与精确值作比较。结果如下图:

(二)OpenMP并行程序设计

实验一:多线程积分求π

由公式:

4dx201x,

1得π的近似值为:

4Ni0.5fNi1N

在for循环之前添加OpenMP的引导语句“#pragma omp parallel for private(x) reduction (+:sum)”,将整个for循环分配到各个线程中去执行,并通过reduction操作将各自的sum和相加得到整个for循环求积分的结果。

一个线程运行时:

五个线程运行时:

十个线程运行时:

实验二:多线程求矩阵乘运算

随着矩阵规模的增加,运行的时间变长。在规模小时,增大线程数时,时间减少不明显,有时还会出现时间增多的情况。规模大时,增大线程数会明显减少运行的时间,但是并不是线性的。当线程数超过最大的节点核数时,随着线程的增多,总的运行时间会变大。

一个线程运行时:

五个线程运行时:

五、实验心得体会

在本次试验中,清楚的掌握了MPI和openMP的基本概念,通过对环境的安装,对两种环境又有了很好的认识。通过在两种环境中的编程实验,对MPI和openMP的并行编程技术有了基本的了解。但是因为时间有限,对两种编程方式还没有很深刻和熟悉的把握,也将在以后工作中继续学习,并掌握进程线程都并行的方法。

六、实验源代码

(一)MPI并行程序设计

实验一:问候发送与接收(mpi_1.cpp)

#include #include #include

int main(intargc,char**argv) {

char message[30]; intrank,size; MPI_Status status; MPI_Init(&argc,&argv);

MPI_Comm_rank(MPI_COMM_WORLD,&rank); MPI_Comm_size(MPI_COMM_WORLD,&size); if(rank!=0) {

sprintf(message,\"greeting from %d.\",rank);

MPI_Send(message,strlen(message),MPI_CHAR,0,10,MPI_COMM_WORLD); }

if(rank==0) {

for(inti=1;iMPI_Recv(message,20,MPI_CHAR,i,10,MPI_COMM_WORLD,&status); printf(\"Receive : %s\\n\",message); }

printf(\"Received all, from process %d\\n\",rank); }

MPI_Finalize(); return0; }

实验二:多进程通过积分求π,并与精确值比较(mpi_2.cpp)

#include #include #include

#define LENG_PER_PRO 10000

#define PI 3.1415926535897932384626433 int main(intargc,char**argv) {

intrank,size;

intnum=LENG_PER_PRO;

double sum=0,block,all,diff; double pi=PI; MPI_Status status; MPI_Init(&argc,&argv);

MPI_Comm_rank(MPI_COMM_WORLD,&rank);

MPI_Comm_size(MPI_COMM_WORLD,&size); block=1/((double)(num*size)); for(inti=0;isum=sum+block*4/(1+((double)(rank*num+i)*(rank*num+i)/(num*size)/(num*size))); }

if(rank==0)

{for(int j=1;jMPI_Recv(&all,1,MPI_DOUBLE,j,0,MPI_COMM_WORLD,&status); sum+=all; }

printf(\"PI is %1.20f \\n\",sum); diff=((sum-pi))/pi;

printf(\"difference is %1.20f\\n\",diff); } else {

MPI_Send(&sum,1,MPI_DOUBLE,0,0,MPI_COMM_WORLD); }

MPI_Finalize(); return0; }

(二)OpenMP并行程序设计

实验一:多线程积分求π(openMP_1.cpp)

#include #include #define STEPS 10000000

#define PI 3.1415926535897932384626433 #define NUM_THREADS 10 int main() {

doublex,sum=0.0,diff; double pi=PI;

double block=1/((double)STEPS); omp_set_num_threads(NUM_THREADS);

#pragma omp parallel for private(x) reduction (+:sum) for(inti=0;ix=(i+0.5)*block; sum+=4/(1+x*x);

}

printf(\"PI is %1.20f .\\n\",sum*block); diff=((sum*block-pi))/pi;

printf(\"difference is %1.20f\\n\",diff); return0; }

实验二:多线程求矩阵乘运算(openMP_2.cpp)

#include #include #include \"sys/time.h\" #define size 100 #define NUM_THREADS 10 int main () {

int z=size;

int a[z][z],b[z][z],c[z][z]; structtimevalstart,end; floatall_time; for(int x=0;xa[x][y]=5; b[x][y]=7; c[x][y]=0; }

gettimeofday(&start,NULL);

omp_set_num_threads(NUM_THREADS); #pragma omp parallel for for(inti=0;ic[i][j]+=a[i][h]*b[h][j]; }

gettimeofday(&end,NULL);

all_time=(end.tv_sec-start.tv_sec)+(float)(end.tv_usec-start.tv_usec)/1000000.0;

for(inti=0;ifor(int j=0;j}

printf(\"run time:\%f s\\n\",all_time); return0; }

因篇幅问题不能全部显示,请点此查看更多更全内容