一、实验目的及要求
熟悉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小时内删除。