一、实验目的及要求 熟悉MPI编程环境,掌握MPI编程基本函数及MPI的相关通信函数用法,掌握MPI的主从模式及对等模式编程; 熟悉OpenMP编程环境,初步掌握基于OpenMP的多线程应用程序开发,掌握OpenMP相关函数以及数据作用域机制、多线程同步机制等。 二、实验设备(环境)及要求 Microsoft Visual Studio 2005 MPICH2 Windows 7 32位 Intel Core2 Duo T5550 1.83GHz 双核CPU 2GB内存 三、实验内容与步骤 1.配置实验环境 v/research/projects/mpich2/downloads/index.php?s=downloads 处下载MPICH2,并安装。 将安装目录中的bin目录添加到系统环境变量path中。进程间通信实验报告心得 以管理员身份运行,输入命令smpd -install -phrase ***。***为安装时提示输入的passphrase。 运行,输入具有系统管理员权限的用户名及密码,进行注册。 配置vs2005,加入MPICH2的包含文件,引用文件和库文件,如下图。 配置项目属性,添加附加依赖项mpi.lib,如下图。 VS2005支持OpenMP,只需在项目属性中做如下配置。 2.编写MPI程序 题目:一个小规模的学校想给每一个学生一个唯一的证件号。管理部门想使用6位数字,但不确定是否够用,已知一个“可接受的”证件号是有一些限制的。编写一个并行计算程序来计算不同的六位数的个数(由0-9组合的数),要求满足以下限制: ●第一个数字不能为0; ●两个连续位上的数字不能相同; ●各个数字之和不能为7、11、13 代码如下。 #include "mpi.h" #include <stdio.h> #include <math.h> #define NUM 6 #define MAX 999999 #define MIN 100000 int check(int n) { int i, x, y, sum; if (n < MIN) { return -1; } sum = 0; for (i=1; i<NUM; i++) { x = (n%(int)pow(10, i))/(int)pow(10,i-1); y = (n%(int)pow(10, i+1))/(int)pow(10, i); if (x == y) { return -1; } sum = sum+x+y; } if (sum==7 || sum==11 || sum==13) { return -1; } return 0; } void main(int argc, char **argv) { int myid, numprocs, namelen; char processor_name[MPI_MAX_PROCESSOR_NAME]; MPI_Status status; double startTime, endTime; int i, mycount, count; MPI_Init(&argc,&argv); MPI_Comm_rank(MPI_COMM_WORLD,&myid); MPI_Comm_size(MPI_COMM_WORLD,&numprocs); MPI_Get_processor_name(processor_name,&namelen); if (myid == 0) { startTime = MPI_Wtime(); } mycount = 0; for (i=myid; i<=MAX; i+=numprocs) { if (check(i) == 0) { mycount++; } } printf("Process %d of %d on %s get result=%d\n", myid, numprocs, processor_name, mycount); if (myid != 0) { MPI_Send(&mycount, 1, MPI_INT, 0, myid, MPI_COMM_WORLD); } else { count = mycount; for (i=1; i<numprocs; i++) { MPI_Recv(&mycount, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); count += mycount; } endTime = MPI_Wtime(); printf("result=%d\n", count); printf("time elapsed %f\n", endTime-startTime); } MPI_Finalize(); } 计算量平均分给每个进程,每个进程将自己计算的部分结果发送给0号进程,由0号进程将结果相加,并输出。 MPI_Init函数进行MPI的初始化,MPI_Comm_size函数获得相关进程数,MPI_Comm_rank函数获得该进程在指定通信因子中的进程号,MPI_Get_processor_name获得进程名。 其他进程使用MPI_Send函数将自己计算的结果发送给0号进程,0号进程使用MPI_Recv函数接受其他进程发送来的结果。 3.编写OpenMP程序 题目:通过计算π的程序,将计算积分的循环并行处理。代码如下。 #include <stdio.h> #include <omp.h> #include <time.h> #define ITRERATION_N (1<<29) int main(int argc, char **argv) { double local, pi=0.0, w = 1.0/ITRERATION_N; long i; clock_t start, end; start = clock(); //并行计算圆周率,利用pi=4*arctan(1) #pragma omp parallel for private(local) reduction(+:pi) for(i=0; i<ITRERATION_N; i++) { local = (i+0.5)*w; pi = pi + 4.0/(1.0+local*local); } end = clock(); printf("PI is %.20f\n", pi*w); printf("%f second(s) elapsed\n", ((double)(end-start))/CLOCKS_PER_SEC); return 0; } 进行2^29次迭代,即将积分区间分为2^29份。使用语句#pragma omp parallel for private(local) reduction(+:pi)将循环并行化,local为各线程私有的,规约时将每个线程计算的循环部分的pi相加起来得到结果。 四、实验结果与数据处理 MPI程序 1个process: 2个process: 计算时间比一个process减少了约50%。 OpenMP程序运行结果 五、分析与讨论 并行计算的性能在绝大多数情况下远高于串行。 MPI为程序员提供一个并行环境库,以实现分布内存环境下的并行编程,程序员通过调用MPI的库程序来达到程序员所要达到的并行目的,可以只使用其中的6个最基本的函数就能编写一个完整的MPI程序去求解很多问题。 OpenMP应用编程接口API是在共享存储体系结构上的一个编程模型,包含编译制导、运行库例程和环境变量,支持增量并行化,已经被大多数计算机硬件和软件厂家所标准化。 OpenMP、MPI混合编程结合两种并行编程模式的优点,用于集环境下的并行编程,在集节点之间采用MPI进行消息传递,节点内部则采用OpenMP实现并行,从而充分发挥集系统的计算能力。 | |
六、教师评语 签名: 日期: | 成绩 |
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论