基於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\n",pi);
          printf("Time = %lf\n",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\n",pi);
        printf("Time = %.8f\n",end-start);
    }
    MPI_Finalize();
    return 0;
} 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM