求解定积分的并行算法——基于MPI

来源:互联网 发布:淘宝卖家软件工具吧 编辑:程序博客网 时间:2024/05/21 10:27

1.算法思路
可以用四个基本步骤去设计一个并行程序:
1)将问题的解决方案划分成多个任务。
2)在任务间识别出需要的通信信道。
3)将任务聚合成复合任务。
4)在核上分配复合任务。
在划分阶段,我们通常试着识别出尽可能多的任务。对于梯形积分法,我们可以识别出两种任务:一种是获取单个矩形区域的面积,另一种是计算这些区域的面积和。然后利用通信信道将每个第一种任务与一个第二种任务相连接。
使用的梯形越多,估计值就越精确。也就是说:应该使用尽可能多的梯形。因此,梯形的数目将超过核的数量,需要将梯形区域面积的计算聚合成组。实现这一目标的一个很自然的方法就是将区间[a,b]分成comm_sz个子区间。如果comm_sz可以整除n,即梯形数目,那么我们可以简单地在n/comm_sz个梯形和所有comm_sz个子空间上应用梯形积分法。最后,我们可以利用进程中的某一个,如0号进程,将这些梯形面积的估计值累加起来,完成整个计算过程。
2.程序源码

#include <stdio.h>#include <mpi.h>#include <ctype.h>#include <string.h>#include <malloc.h>#include <math.h>#define PI  3.1415926535898double Integral(double a,double b,double (*fun)(double)){   int i,l;    double n=0.001,s=0;    l=(b-a)/n;    double top,base;    for(i=0;i<l;i++)    {        top=(*fun)(a+n*i);        base=(*fun)(a+n*(i+1));        s=(top+base)*n/2+s;    }    printf("cos(x)在(%lf,%lf)上的积分为%lf\n",a,b,s);    return s;}int main(int argc,char** argv){    MPI_Comm comm = MPI_COMM_WORLD;    int size,rank;    MPI_Init(&argc,&argv);    MPI_Comm_size(comm,&size);    MPI_Comm_rank(comm,&rank);    int i;    double sum=0;    double a=0;    double b=2*PI;    double n=(b-a)/size;    double *sbuf=(double *)malloc(sizeof(double)* size);    double *rbuf=(double *)malloc(sizeof(double)* size);    double *start=(double *)malloc(sizeof(double)*1);    double *part=(double *)malloc(sizeof(double)*1);    if(rank==0){       for(i=0;i<size;i++)        sbuf[i]=a+n*i;    }MPI_Scatter(sbuf,1,MPI_DOUBLE,start,1,MPI_DOUBLE,0,comm); (*part)=Integral((*start),(*start)+n,cos);    MPI_Gather(part,1,MPI_DOUBLE,rbuf,1,MPI_DOUBLE,0,comm);    if(rank==0){    for(i=0;i<(size+1);i++)    {      sum+=rbuf[i];    }    printf("cos(x)在(%lf,%lf)的定积分为%lf\n",a,b,sum);    }    MPI_Finalize();    return 0;}

3.运行结果
并行:这里写图片描述
这里写图片描述

串行这里写图片描述
:
4.性能分析
在同样的环境中,计算相同的积分,通过比较串行程序和并行程序的运行时间可知,并行程序的运行时间较长

原创粉丝点击