MPI并行计算——点对点通信(求Cos(x)dx的积分)

环境

  • centos7
  • mpi 3.2

要求

求cosxdx在a到b区间的积分可以由上图方法近似,图中p是process进程的数量,n是划分小长方形的数量,在输入的时候给出。

代码

注:本代码输入的时候b和a是角度值

#include "mpi.h"
#include <stdio.h>
#include <math.h>
#include <string.h>
#define PI acos(-1.0)
double to_rad(double degree){
		return degree / 180 * PI;
}
	
int main(int argc,char **argv){
		int size,rank;
		
		MPI_Comm comm = MPI_COMM_WORLD;
		MPI_Status status;
		MPI_Init(&argc,&argv);
		MPI_Comm_size(comm,&size);
		MPI_Comm_rank(comm,&rank);
		if(rank == 0) {
			int n;
			double b,a;
			printf("input a num\n");
			scanf("%d",&n);
			printf("then input b and a\n");
			scanf("%lf %lf",&b, &a);
			if(b < a){//防止输错
				double tmp = a;
				a = b;
				b = tmp;
			}
			for(int i = 1;i < size;i++){
					MPI_Send(&n,1,MPI_INT,i,99,comm);
					MPI_Send(&a,1,MPI_DOUBLE,i,99,comm);
					MPI_Send(&b,1,MPI_DOUBLE,i,99,comm);
			}
			int p = size;
			
			double h = (to_rad(b) - to_rad(a))/p/n;
			double sum = 0.0;
			for(int i = 0;i < n;i++) {
					double num = to_rad(a) + (rank*n + i)*h;
					sum += cos(num + h/2)*h;
				}
			for(int i = 1;i < size;i++) {
				double tmp_num;
				MPI_Recv(&tmp_num,1,MPI_DOUBLE,i,99,comm,&status);
				sum += tmp_num;
			}
			printf("区间(a,b) cosdx 的积分 = %.3lf\n",sum);
			
		}
		else {
				int p = size;
				int n;
				double b,a;
				MPI_Recv(&n,1,MPI_INT,0,99,comm,&status);
				MPI_Recv(&a,1,MPI_DOUBLE,0,99,comm,&status);
				MPI_Recv(&b,1,MPI_DOUBLE,0,99,comm,&status);
				double h = (to_rad(b) - to_rad(a))/p/n;
				printf("PI_%lf  h_%lf\n",PI,h);//中间结果
				
				double sum = 0.0;
				for(int i = 0;i < n;i++) {
					double num = to_rad(a) + (rank*n + i)*h;
					sum += cos(num + h/2)*h;
					
				}
				printf("cos(x)%d = %.3lf\n",rank,sum);//中间结果
				MPI_Send(&sum,1,MPI_DOUBLE,0,99,comm);
		}
		MPI_Finalize();
	  return 0;
}

猜你喜欢

转载自blog.csdn.net/a429367172/article/details/88581526
今日推荐