1. 程式人生 > >平行計算之梯形積分

平行計算之梯形積分

方法1

#include<stdio.h>
#include"mpi.h"
double Trap(double left_endpt,double right_endpt,int trap_count,double base_len);
double f(double x);

int main(void)
{
  int my_rank,comm_sz,n = 1024,local_n;
  double a = 0.0, b= 1.0 , h, local_a,local_b;
  double local_int,total_int;
  int source;
 
  MPI_Init(NULL,NULL);
  MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);
  MPI_Comm_size(MPI_COMM_WORLD,&comm_sz);
  
  Get_input(my_rank, comm_sz, &a, &b, &n);
 
  h = (b-a)/n;
  local_n= n/comm_sz;
 
  local_a = a+my_rank * local_n * h;
  local_b = local_a + local_n * h;
  local_int = Trap(local_a ,local_b,local_n,h);

  if(my_rank!=0)		
  {
     MPI_Send(&local_int,1,MPI_DOUBLE,0,0,MPI_COMM_WORLD);
  }
  else
  {
     total_int = local_int;
	 for(source =1; source <comm_sz; source++)
	 {
	    MPI_Recv(&local_int,1,MPI_DOUBLE,source,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
		total_int += local_int;
	 }
  }
  if(my_rank == 0)
  {
    printf("with n = %d trapezoids, our estimate\n",n);
	printf("of the integral from %f to %f = %.15e\n",a,b,total_int);
  }
 
  MPI_Finalize();
  return 0;
}
 
double Trap(double left_endpt,double right_endpt,int trap_count,double base_len)
{
  double estimate,i;
  int x;
  estimate = (f(left_endpt) + f(right_endpt))/2.0;
  for(i = 1; i <= trap_count-1 ; i++)
  {
    x = left_endpt + i*base_len;
	estimate += f(x);
  }
  estimate = estimate*base_len;
  return estimate;
}
 
double f(double x)
{
	return 4/(1+x*x);
}

VC6執行效果圖


方法2(用到了MPI_Reduce()函式)

#include<stdio.h>
#include"mpi.h"
double Trap(double left_endpt,double right_endpt,int trap_count,double base_len);
double f(double x);
int main(void)
{
  int my_rank,comm_sz,n = 1024,local_n;
  double a = 0.0, b= 1.0 , h, local_a,local_b;
  double local_int,total_int;
  int source;

  MPI_Init(NULL,NULL);
  MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);
  MPI_Comm_size(MPI_COMM_WORLD,&comm_sz);

  h = (b-a)/n;
  local_n= n/comm_sz;

  local_a = a+my_rank * local_n * h;
  local_b = local_a + local_n * h;
  local_int = Trap(local_a ,local_b,local_n,h);
  MPI_Reduce(&local_int, &total_int, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);<span style="white-space:pre">	</span>//2
  if(my_rank == 0)
  {
    printf("with n = %d trapezoids, our estimate\n",n);
	printf("of the integral from %f to %f = %.15e\n",a,b,total_int);
  }

  MPI_Finalize();
  return 0;
}

double Trap(double left_endpt,double right_endpt,int trap_count,double base_len)
{
  double estimate,i;
  int x;
  estimate = (f(left_endpt) + f(right_endpt))/2.0;
  for(i = 1; i <= trap_count-1 ; i++)
  {
    x = left_endpt + i*base_len;
	estimate += f(x);
  }
  estimate = estimate*base_len;
  return estimate;
}

double f(double x)
{
	return 4/(1+x*x);
}

VC6執行效果圖

方法3(用到了MPI_Bcast()函式進行廣播)

#include<stdio.h>
#include"mpi.h"
double Trap(double left_endpt,double right_endpt,int trap_count,double base_len);
double f(double x);
void Get_input(			//3,用於輸入資料
	int my_rank,
	int comm_sz,
	double* a_p,
	double* b_p,
	double* n_p) {

	if (my_rank==0) {
		printf("Enter a, b, and n\n");
		scanf("%lf %lf %d", a_p, b_p, n_p);
	}
	MPI_Bcast(a_p, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
	MPI_Bcast(b_p, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
	MPI_Bcast(n_p, 1, MPI_INT, 0, MPI_COMM_WORLD);
}
int main(void)
{
  int my_rank,comm_sz,n = 1024,local_n;
  double a = 0.0, b= 1.0 , h, local_a,local_b;
  double local_int,total_int;
  int source;

  MPI_Init(NULL,NULL);
  MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);
  MPI_Comm_size(MPI_COMM_WORLD,&comm_sz);

  Get_input(my_rank, comm_sz, &a, &b, &n);

  h = (b-a)/n;
  local_n= n/comm_sz;

  local_a = a+my_rank * local_n * h;
  local_b = local_a + local_n * h;
  local_int = Trap(local_a ,local_b,local_n,h);
  MPI_Reduce(&local_int, &total_int, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
  if(my_rank == 0)
  {
    printf("with n = %d trapezoids, our estimate\n",n);
	printf("of the integral from %f to %f = %.15e\n",a,b,total_int);
  }

  MPI_Finalize();
  return 0;
}

double Trap(double left_endpt,double right_endpt,int trap_count,double base_len)
{
  double estimate,i;
  int x;
  estimate = (f(left_endpt) + f(right_endpt))/2.0;
  for(i = 1; i <= trap_count-1 ; i++)
  {
    x = left_endpt + i*base_len;
	estimate += f(x);
  }
  estimate = estimate*base_len;
  return estimate;
}

double f(double x)
{
	return 4/(1+x*x);
}

VC6執行效果圖

MPI執行效果圖