並行程式設計報告(MPI平行計算π,實現mandelbrot集)
阿新 • • 發佈:2019-01-10
一.熟悉MPI並行程式設計環境
1.硬體
電腦:HP暗夜精靈
記憶體:4G
處理器:ntel® Core™ i5-6300HQ CPU @ 2.30GHz × 4
顯示卡:NVIDIA 960M
2.軟體
系統:Ubuntu 16.04LTS
MPI版本:MPICH2
二.計算
1.問題描述
已知計算公式: 已知有如下兩種演算法求其數值積分:
- 1.用梯形面積進行數值計算
- 2.用矩形面積進行數值計算
2.程式概要設計(用梯形法計算)
MPI_Bcast(&n,1,MPI_INT,0 ,MPI_COMM_WORLD);//把n廣播給所有程序
MPI_Barrier(MPI_COMM_WORLD);
init_size=1.0/n;//把圖形分為n個梯形,每個梯形的高為1/n
for(int i=rank+1;i<=n;i+=proc_num)//每個程序計算n/proc_num個梯形
{
x1=init_size*(i);
x2=init_size*(i-1);
x1=4/(1+x1*x1);
x2=4/(1+x2*x2);
part_sum=part_sum+x1+x2;//把梯形的上底和下底計算到部分和中
}
temp_pi=init_size*part_sum/2;//計算該程序所計算的梯形面積和
//歸約函式,對所有程序所計算的面積求和即是pi值
MPI_Reduce(&temp_pi,&cal_pi,1,MPI::DOUBLE,MPI::SUM,0,MPI_COMM_WORLD);
3.實驗結果及其分析
分割塊數 | 50000 | 100000 | 1000000 | 10000000 | 100000000 |
---|---|---|---|---|---|
無並行(執行時間 s) | 0.00429 | 0.00620 | 0.05238 | 0.29442 | 2.79347 |
兩個程序並行(執行時間 s) | 0.00074 | 0.00145 | 0.01370 | 0.13708 | 1.38299 |
三個程序並行(執行時間 s) | 0.00052 | 0.00098 | 0.00936 | 0.08995 | 0.92909 |
四個程序並行(執行時間 s) | 0.00040 | 0.00074 | 0.00743 | 0.07731 | 0.77368 |
五個程序並行(執行時間 s) | 0.02835 | 0.03105 | 0.05499 | 0.12929 | 1.19763 |
六個程序並行(執行時間 s) | 0.03948 | 0.04632 | 0.05634 | 0.13655 | 1.10347 |
部分結果截圖如下:
結果分析:
分割塊數 | 50000 | 100000 | 1000000 | 10000000 | 100000000 |
---|---|---|---|---|---|
無並行(加速比) | 1 | 1 | 1 | 1 | 1 |
兩個程序並行(加速比) | 5.79 | 4.27 | 3.82 | 2.14 | 2.01 |
三個程序並行(加速比) | 8.25 | 6.33 | 5.59 | 3.27 | 3.01 |
四個程序並行(加速比) | 10.73 | 8.38 | 7.05 | 3.80 | 3.61 |
五個程序並行(加速比) | 0.15 | 0.20 | 0.95 | 5.35 | 2.33 |
六個程序並行(加速比) | 0.11 | 0.13 | 0.92 | 2.15 | 2.53 |
從上圖可知,在我的計算機上當開四個程序時效能達到最大,因為我的計算機是四核的可以做到四個程序真正的並行 .當資料兩較小時,無並行的比並行的更快的主要原因是計算量小的時候MPI通訊的時間佔了程序時間開銷的大部分.
三.Mandelbrot集
1.問題描述
曼德勃羅特集是人類有史以來做出的最奇異,最瑰麗的幾何圖形,曾被稱為”上帝的指紋”. 這個點集均出自公式,所有使得無限迭代後的結果能保持有限數值的複數c的集合構成曼德勃羅特集.假定迭代一定次數後的複數即為曼德勃羅特數,計算一定區間的曼德勃羅特集,並根據數字不同的迭代次數給該點設為不同的顏色.滑動滑鼠,即可計算一定區域的曼德勃羅特集並顯示出來
2.程式概要設計
把區域分為的區域按順序依次分給空閒的程序
//定義Zn+1=Zn^2+c的運算
ComplexNumber f(ComplexNumber z, ComplexNumber c)
{
ComplexNumber result;
result.real=c.real+z.real*z.real-z.imag*z.imag;
result.imag=c.imag+z.imag*z.real+z.real*z.imag;
return result;
}
//定義曼德勃羅特的計算步驟,並在recv陣列中記錄該點迭代的次數
void Mandelbrot(double Xmin,double dx, int xloop, int xfrom, double Ymin, double dy, int yloop, int yfrom)
{
int x, y, k;
ComplexNumber c, z;
for (x=0; x<xloop; x++)
{
c.real = Xmin+x*dx;
for (y=0; y<yloop; y++)
{
c.imag = Ymin+y*dy;
z.real = z.imag = 0.0f;
k = 0;
while (k<MAX_ITERATE_DEPTH && (z.real*z.real+z.imag*z.imag)<=MAX_MAGNITUDE)
{
z = f(z, c);
k++;
}
recv[xfrom+x][yfrom+y] = k;
}
}
}
// 對於一個程序如果接收到了再計算的命令,就計算分配給他的區域的曼德勃羅特集,區域資訊存在info結構體中
if (Redo == status.MPI_TAG)
{
MPI_Recv(&info,1,AreaType,0,Redo,MPI_COMM_WORLD,&status);
int txfrom=(info.xloop%slave_num)*info.sub_xloop;
double tymin=(info.xloop/slave_num)*info.Yarea/slave_num+info.Ymin;
int tyfrom=(info.xloop/slave_num)*info.sub_yloop;
Mandelbrot(txmin,info.dx,info.sub_xloop,txfrom,tymin,info.dy,info.sub_yloop,tyfrom);
MPI_Send(&info.xloop,1,MPI_INT,0,Over,MPI_COMM_WORLD);
MPI_Send(recv,PIXEL_NUM,MPI_SHORT,0,Over,MPI_COMM_WORLD);
printf("send from slave %d\n", rank-1);
}
//opengl的閒時回撥函式,主程序一直再執行該函式,接受子程序的資料,當接受到一個程序發來的資料時,
主程序判斷還有無未計算的區域,如果有就分配給該程序
void Idle()
{
//printf("34");
static int recved = 0;
int pos;
int i, j, x, y;
int xfrom, yfrom;
int flag, slave_rank;
MPI_Status status;
MPI_Iprobe(MPI_ANY_SOURCE,Over,MPI_COMM_WORLD, &flag, &status);
if (!flag) return;
MPI_Recv(&pos,1,MPI_INT,status.MPI_SOURCE,Over,MPI_COMM_WORLD,&status);
MPI_Recv(recv,PIXEL_NUM,MPI_SHORT,status.MPI_SOURCE,Over,MPI_COMM_WORLD,&status);
if (slave_num*slave_num== ++recved)
{
recved = 0;
end_time = MPI_Wtime();
printf("wall clock time = %f\n", end_time-start_time);
}
slave_rank = status.MPI_SOURCE-1;
printf("recieve from slave %d\n", slave_rank);
i = slave_rank;
xfrom = (pos%slave_num)*info.sub_xloop;
yfrom = (pos/slave_num)*info.sub_yloop;
for(x=0; x<info.sub_xloop; x++)
{
for (y=0; y<info.sub_yloop; y++)
indices[xfrom+x][yfrom+y] = recv[xfrom+x][yfrom+y];
}
if(count<slave_num*slave_num)
{
MPI_Send(&part[count],1,AreaType,slave_rank+1,Redo,MPI_COMM_WORLD);
count++;
}
glutPostRedisplay();
}
3實驗.結果及其分析