并行程序设计报告(MPI并行计算π,实现mandelbrot集)
代碼的github地址
一.熟悉MPI并行程序設(shè)計(jì)環(huán)境
1.硬件
電腦:HP暗夜精靈
內(nèi)存:4G
處理器:ntel? Core? i5-6300HQ CPU @ 2.30GHz × 4
顯卡:NVIDIA 960M
2.軟件
系統(tǒng):Ubuntu 16.04LTS
MPI版本:MPICH2
二.計(jì)算π\(zhòng)piπ
1.問題描述
已知π\(zhòng)piπ計(jì)算公式:π=∫0141+x2dx\pi=\int_{0}^{1}{\frac{4}{1+x^2}}dxπ=∫01?1+x24?dx已知有如下兩種算法求其數(shù)值積分:
- 1.用梯形面積進(jìn)行數(shù)值計(jì)算
- 2.用矩形面積進(jìn)行數(shù)值計(jì)算
2.程序概要設(shè)計(jì)(用梯形法計(jì)算)
MPI_Bcast(&n,1,MPI_INT,0,MPI_COMM_WORLD);//把n廣播給所有進(jìn)程MPI_Barrier(MPI_COMM_WORLD);init_size=1.0/n;//把圖形分為n個(gè)梯形,每個(gè)梯形的高為1/nfor(int i=rank+1;i<=n;i+=proc_num)//每個(gè)進(jìn)程計(jì)算n/proc_num個(gè)梯形{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;//把梯形的上底和下底計(jì)算到部分和中}temp_pi=init_size*part_sum/2;//計(jì)算該進(jìn)程所計(jì)算的梯形面積和//歸約函數(shù),對(duì)所有進(jìn)程所計(jì)算的面積求和即是pi值 MPI_Reduce(&temp_pi,&cal_pi,1,MPI::DOUBLE,MPI::SUM,0,MPI_COMM_WORLD);
3.實(shí)驗(yàn)結(jié)果及其分析
| 分割塊數(shù) | 50000 | 100000 | 1000000 | 10000000 | 100000000 |
|---|---|---|---|---|---|
| 無(wú)并行(運(yùn)行時(shí)間 s) | 0.00429 | 0.00620 | 0.05238 | 0.29442 | 2.79347 |
| 兩個(gè)進(jìn)程并行(運(yùn)行時(shí)間 s) | 0.00074 | 0.00145 | 0.01370 | 0.13708 | 1.38299 |
| 三個(gè)進(jìn)程并行(運(yùn)行時(shí)間 s) | 0.00052 | 0.00098 | 0.00936 | 0.08995 | 0.92909 |
| 四個(gè)進(jìn)程并行(運(yùn)行時(shí)間 s) | 0.00040 | 0.00074 | 0.00743 | 0.07731 | 0.77368 |
| 五個(gè)進(jìn)程并行(運(yùn)行時(shí)間 s) | 0.02835 | 0.03105 | 0.05499 | 0.12929 | 1.19763 |
| 六個(gè)進(jìn)程并行(運(yùn)行時(shí)間 s) | 0.03948 | 0.04632 | 0.05634 | 0.13655 | 1.10347 |
部分結(jié)果截圖如下:
結(jié)果分析:
| 分割塊數(shù) | 50000 | 100000 | 1000000 | 10000000 | 100000000 |
|---|---|---|---|---|---|
| 無(wú)并行(加速比) | 1 | 1 | 1 | 1 | 1 |
| 兩個(gè)進(jìn)程并行(加速比) | 5.79 | 4.27 | 3.82 | 2.14 | 2.01 |
| 三個(gè)進(jìn)程并行(加速比) | 8.25 | 6.33 | 5.59 | 3.27 | 3.01 |
| 四個(gè)進(jìn)程并行(加速比) | 10.73 | 8.38 | 7.05 | 3.80 | 3.61 |
| 五個(gè)進(jìn)程并行(加速比) | 0.15 | 0.20 | 0.95 | 5.35 | 2.33 |
| 六個(gè)進(jìn)程并行(加速比) | 0.11 | 0.13 | 0.92 | 2.15 | 2.53 |
從上圖可知,在我的計(jì)算機(jī)上當(dāng)開四個(gè)進(jìn)程時(shí)性能達(dá)到最大,因?yàn)槲业挠?jì)算機(jī)是四核的可以做到四個(gè)進(jìn)程真正的并行 .當(dāng)數(shù)據(jù)兩較小時(shí),無(wú)并行的比并行的更快的主要原因是計(jì)算量小的時(shí)候MPI通信的時(shí)間占了進(jìn)程時(shí)間開銷的大部分.
##三.Mandelbrot集##
1.問題描述
曼德勃羅特集是人類有史以來(lái)做出的最奇異,最瑰麗的幾何圖形,曾被稱為"上帝的指紋". 這個(gè)點(diǎn)集均出自公式zn+1=zn2+cz_{n+1}=z_n^2+czn+1?=zn2?+c,所有使得無(wú)限迭代后的結(jié)果能保持有限數(shù)值的復(fù)數(shù)c的集合構(gòu)成曼德勃羅特集.假定迭代一定次數(shù)后的復(fù)數(shù)即為曼德勃羅特?cái)?shù),計(jì)算一定區(qū)間的曼德勃羅特集,并根據(jù)數(shù)字不同的迭代次數(shù)給該點(diǎn)設(shè)為不同的顏色.滑動(dòng)鼠標(biāo),即可計(jì)算一定區(qū)域的曼德勃羅特集并顯示出來(lái)
2.程序概要設(shè)計(jì)
把區(qū)域分為n?nn*nn?n的區(qū)域按順序依次分給空閑的進(jìn)程
//定義Zn+1=Zn^2+c的運(yùn)算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; }
//定義曼德勃羅特的計(jì)算步驟,并在recv數(shù)組中記錄該點(diǎn)迭代的次數(shù)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; } } }
// 對(duì)于一個(gè)進(jìn)程如果接收到了再計(jì)算的命令,就計(jì)算分配給他的區(qū)域的曼德勃羅特集,區(qū)域信息存在info結(jié)構(gòu)體中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的閑時(shí)回調(diào)函數(shù),主進(jìn)程一直再執(zhí)行該函數(shù),接受子進(jìn)程的數(shù)據(jù),當(dāng)接受到一個(gè)進(jìn)程發(fā)來(lái)的數(shù)據(jù)時(shí),主進(jìn)程判斷還有無(wú)未計(jì)算的區(qū)域,如果有就分配給該進(jìn)程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實(shí)驗(yàn).結(jié)果及其分析
總結(jié)
以上是生活随笔為你收集整理的并行程序设计报告(MPI并行计算π,实现mandelbrot集)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《庾楼新岁》是谁的作品?
- 下一篇: 矩阵奇异值分解的几何意义(入门级教程)