由0号进程读进a和b,广播到全部线程分别计算自己的区域。
线程数要取得适当,可以取得不错的加速效果。
C++源码
#include<sys/time.h>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<mpi.h>
using namespace std ;
const double eps = 1e-12 ;
double a ,b ,res , a0 , b0 ,res0 ;
double f(double x)
{
return sin(x)/x ;
}
double simpson(double l , double r)
{
double mid = (l+r) / 2 ;
return (r-l) * (f(l) + 4*f(mid) + f(r)) / 6 ;
}
double asr(double l , double r , double area)
{
double mid = (l + r ) / 2 ;
double left = simpson(l , mid) , right = simpson(mid, r) ;
if(fabs(left + right - area) < eps ) return left + right ;
else return asr( l ,mid , left) + asr(mid , r , right ) ;
}
int main()
{
int nprocs = 0 , my_rank = 0 ;
MPI_Init(NULL, NULL) ;
MPI_Comm_rank(MPI_COMM_WORLD , &my_rank);
MPI_Comm_size(MPI_COMM_WORLD , &nprocs) ;
int start = clock() ;
if(my_rank==0)
{
scanf("%lf%lf",&a,&b) ;
}
MPI_Bcast(&a , 1 , MPI_DOUBLE , 0 , MPI_COMM_WORLD) ;
MPI_Bcast(&b , 1 , MPI_DOUBLE , 0 , MPI_COMM_WORLD) ;
a0 = a + my_rank * (b-a) / nprocs ;
b0 = a + (my_rank + 1 )*(b-a) / nprocs ;
res0 = asr(a0,b0,simpson(a0,b0)) ;
MPI_Reduce(&res0 , &res , 1 , MPI_DOUBLE , MPI_SUM , 0 , MPI_COMM_WORLD) ;
if(my_rank == 0 )
{
printf("result=%lf\n" , res) ;
printf("time : %lf ms\n" , (double)(clock() - start ) / CLOCKS_PER_SEC * 1000 ) ;
}
MPI_Finalize() ;
return 0 ;
}
编译命令(我的本地c++文件名叫“integration”)
cd "/home/yining/mpi/mpich-3.4.1/examples/my_mpi/code/integration/" && mpicxx -o integration integration.cpp && mpirun -n $mpi_n ./integration
更一般的,指令如下格式
"cpp": "cd $dir && mpicxx -o $fileNameWithoutExt $fileName && mpirun -n $mpi_n ./$fileNameWithoutExt"
其中,$mpi_n 是我本地Linux的变量,指的线程个数,需要每次打开bash重新设置。
执行效果如下:
粗略计算,加速了大约十倍左右。但是不要高兴的太早。因为每一次的执行效果都有所不同。可能和机器当前运转状态有关系。