您的位置:首页 > 其它

并行计算MPI(三):计算π

2015-03-11 13:54 253 查看
学习了之前的一些并行计算MPI基本知识之后,其实可以尝试应用起来,今天这篇文章就是用并行计算求解π的。首先需要知道π的求解方式:



上面是高等数学里的基本知识,所以π的求解就可以变为求解y(x)=4/(1+x^2)在(0,1)区间的面积。而且求解面积这一块可以采用将(0,1)平均分n个块,将n个矩形面积相加即可得到近似解。而且n取得越大,近似解越精确。

比如我们取n=100,开4个进程来处理,那么相应的每个进程平均分到计算25个矩形面积,如果开5个进程,那么平均分下来每个进程计算20个矩形面积。下面列出代码:

//返回函数值,因为调用次数很多,这里写成inline提高效率
inline double f(double x) {
return 4/(1+x*x);
}

int main(int argc, char *argv[]) {
double pi, h, sum, x, startime, endtime;
int size, myid;
long long n;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
MPI_Comm_size(MPI_COMM_WORLD, &size);

n=0;
if(0 == myid) {
cout << "Please enter n" << endl;
cin >> n;
startime = MPI_Wtime();
}
MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);  //将n广播到所有进程中
h = 1.0/(double)n;							   //每个矩形块的宽
sum = 0.0;
for(int i=myid+1; i<=n; i+=size) {             //4个进程
x = h*((double)i - 0.5);                   //进程0:1,5,9,...  进程1:2,6,10,...
sum = sum + f(x);                          //进程2:3,7,11,... 进程3:4,8,12,...
}
sum = sum * h;								   //每个进程计算的矩形面积之和
MPI_Reduce(&sum, &pi, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);  //利用归约操作(MPI_SUM)将所有进程的sum累加到root进程(0)的sum当中得到结果
if(myid == 0) {
endtime = MPI_Wtime();
printf("用时:%f\n", endtime-startime);
printf("%0.15f\n", pi);
}
下面是测试结果:











这里n取100000000,是为了计算结果精确一些。实验室机器是单核CPU,而且处理能力不是很强。可以发现4个进程获得的效果是最好的,但是当进程数增加的时候,时间反而会增加,原因应该是当进程太大,那么进程之间的通信成了最主要的瓶颈了。对于这个例子而言,其实主要就是最后一步MPI_Reduce这个操作是进程之间进行了通信,也是比较耗时的地方。而且更主要的是本机是单核的,可能最适合的4个进程,如果是多核的话那么肯定会有其他比较合适的进程数。所以并不是进程数越多越好,而是要结合具体的情况平衡进程数和进程之间通信来编写程序。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: