• 基于MPI计算π值


    1.思路:

    原理根据如下图所进行计算,就是通过定积分定义来进行计算。

    就是这个原理

    2.代码

    方法一:所有进程参与计算,最终每个进程计算的和再在0号进程里面相加,在0号进程打印,代码如下:

    #include<stdio.h>
    #include<mpi.h>
    int main(int argc,char *argv[])
    {
        int myid,np,i,j;
        int tag=666;
        double pi=0.0; 
        double fVal;//fVal代表取Xi所对应的函数值   4/(1+x^2) 即每个矩形的高度
        int n=100000000;
        MPI_Status status;
        double h=(double)1/n; //每个矩形的宽度
        double local=0.0;//每个进程计算的面积和 
        double start,end;
        double xi;
        MPI_Init(&argc,&argv);//启动并行程序    
        MPI_Comm_size(MPI_COMM_WORLD,&np);//获取进程总数
        MPI_Comm_rank(MPI_COMM_WORLD,&myid);//获取当前进程号
        start=MPI_Wtime();//记录开始时间
        for(i=myid;i<n;i+=np) //利用np个进程同时计算各部分矩形面积
        {
                xi=(i+0.5)*h;
                fVal=4.0/(1.0+xi*xi);//得到f(xi) 
                local+=fVal ; 
        }
        local=local*h;//得到该进程所计算的面积 
     
        //进程号!=0的进程计算的结果发送到进程0上面 
        if(myid!=0)
       {   
            MPI_Send(&local,1,MPI_DOUBLE,0,myid,MPI_COMM_WORLD); 
        }
        if(myid==0) //进程号为0就累加每个进程的计算结果 
        {
            pi=local;//得到进程0的值 后面接收就会覆盖这个值 
            for(j=1;j<np;j++)
               {
                    MPI_Recv(&local,1,MPI_DOUBLE,j,j,MPI_COMM_WORLD,&status); //把其他进程的结果发送到local中 
                    pi+=local;//得到所有的面积和 
               }
        }
        end=MPI_Wtime();//结束计算时间 
        if(myid==0)
            {
              printf("PI = %.15f
    ",pi);
              printf("Time = %lf
    ",end-start); 
              }
        MPI_Finalize();
        return 0;
    } 

    方法二:前np-1个计算相应部分的矩形面积,最后一个进程计算前面np-1个所计算的和,代码如下:

    #include<stdio.h>
    #include<mpi.h>
    ///////////////
    //利用一个进程求其他进程所计算的和 
    //////////////
    
    int main(int argc,char *argv[])
    {
        int myid,np,i;
        int tag=666;
        double pi=0.0; 
        double sum=0.0,local=0.0,fVal;//fVal代表取Xi所对应的函数值   4/(1+x^2)
        int n=100000000;
        double start,end;
        MPI_Status status;
        double h=1.0/n; 
        MPI_Init(&argc,&argv);//启动并行程序    
        MPI_Comm_size(MPI_COMM_WORLD,&np);//获取进程总数
        MPI_Comm_rank(MPI_COMM_WORLD,&myid);//获取当前进程号
        start=MPI_Wtime();
        for(i=myid;i<n;i+=(np-1)) //此处最后一个进程不参与计算
        {
            double xi=((double)i+0.5)*h;
            fVal=4.0/(1.0+xi*xi);
            local+=fVal;
        }
        local=local*h;
         //前np-1个进程的计算结果发给最后一个进程
        if(myid!=np-1)  MPI_Send(&local,1,MPI_DOUBLE,np-1,myid,MPI_COMM_WORLD);
       
        if(myid==np-1) //最后一个进程计算前面所有进程计算的面积和
        {
             int j=0;
             for(;j<np-1;j++)
             {
                 MPI_Recv(&sum,1,MPI_DOUBLE,j,j,MPI_COMM_WORLD,&status);
                 pi+=sum;
             } 
                
        }
        end=MPI_Wtime();
        if(myid==np-1) //打印出PI值
        {
            printf("PI = %.15f
    ",pi);
            printf("Time = %.8f
    ",end-start);
        }
        MPI_Finalize();
        return 0;
    } 
  • 相关阅读:
    Scott的ASP.net MVC框架系列文章之一
    NHibernate配置的总体流程(转载)
    深入浅出MFC》学习笔记之一
    用javascript实现选择下拉菜单间的数据转移,用javascript实现超强的万年历,javascript弹出窗口后,关闭窗口时不弹出对话框
    深入理解动态库
    C#中读取文件内容
    a id="saveButton" href="#" onclick="javascript:startUpload();"Upload !!/a
    如何调用DLL (基于Visual C++6.0的DLL编程实现)
    MSDN获取网站,www.bd66.com
    应用MFC开发高级应用程序
  • 原文地址:https://www.cnblogs.com/Juice-Dreamer/p/10968801.html
Copyright © 2020-2023  润新知