pi值 = y(x)=4/(1+x^2)
在(0,1)区间的面积。而且求解面积这一块可以采用将(0,1)平均分n个块,将n个矩形面积相加即可得到近似解。而且n取得越大,近似解越精确。
# include "stdio.h"
# include "mpi.h"
# include "stdlib.h"
# include "math.h"
void calc(double *size, double start_x, double end_x, double num){
*size = 0;
double gap = (end_x - start_x) / num;
for (int i = 0; i < num; ++i) {
*size += (4 / (1 + pow(start_x + i * gap, 2))) * gap;
}
}
int main(int args, char **argv){
int nums_of_square = strtol(argv[1], NULL, 10);
MPI_Init(&args, &argv);
int process_id;
MPI_Comm_rank(MPI_COMM_WORLD, &process_id);
int process_num;
MPI_Comm_size(MPI_COMM_WORLD, &process_num);
double * handle_list = malloc(sizeof (double) * (process_num) * 3);
if (process_id == 0){ // 为数据分发做准备
double k = 0;
double gap = 1.0 / process_num;
for (int i = 0; i < process_num * 3; i += 3) { // 每个进程接收三个数据,区间开始,区间结束,区间分块数
handle_list[i] = k;
handle_list[i + 1] = k + gap;
handle_list[i + 2] = nums_of_square / process_num;
k += gap;
if (i == (process_num) * 3 - 3) {
handle_list[i + 1] = 1.0;
handle_list[i + 2] += nums_of_square % (process_num);
}
}
}
double recv_data[3];
MPI_Scatter(handle_list, 3, MPI_DOUBLE, &recv_data,
3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
double size;
double *recv_size_0 = malloc(sizeof (double ) * (process_num));
calc(&size, recv_data[0], recv_data[1], recv_data[2]);
printf("%d : %f ", process_id, size);
MPI_Gather(&size, 1, MPI_DOUBLE, recv_size_0,
1, MPI_DOUBLE, 0,MPI_COMM_WORLD);
if (process_id == 0) {
double pi = 0;
for (int i = 0; i < process_num; ++i) {
pi += recv_size_0[i];
}
printf("%f", pi);
}
MPI_Finalize();
return 0;
}
"C:\Program Files\Microsoft MPI\Bin\mpiexec.exe" -np 12 ./MPI_calculate_pi 120000000
9 : 0.204949
11 : 0.173804
8 : 0.221994
6 : 0.257707
1 : 0.328030
5 : 0.275426
10 : 0.188836
3 : 0.307088
7 : 0.239713
4 : 0.292162
0 : 0.332565 3.141593
2 : 0.319320
Comments | NOTHING