第十四章 分布存储系统并行编程 习题例题: 1、试考虑下述代码段中通信体的使用; process 0: MPI_Send(msg1,count1,MPI_INT,tag1,comm1); parallel_fft(...); process 1: MPI_Recv(msg1,count1,MPI_INT,tag1,comm1); parallel_fft(...); ⑴试分析上述代码段的计算功能。 ⑵如果在parallel_fft(...)中又包含了另一个发送程序: If(my_rank = = 0) MPI_Send(msg2,count1,MPI_INT,1,tag2,comm2); 如果没有通信体则会发生什么情况? 2、填上空白处,使下面两代码段完全等效: ⑴float data[1024]; MPI_Datatype floattype; MPI_Type_vector(10,1,32,MPI_FLOAT,&floattype); MPI_Type_commit(&floattype); MPI_Send(data,1,floattype,dest,tag,MPI_COMM_WORLD); MPI_Type_free(&floattype); ⑵float data[1024],buff[10]; for( ______ ; ______ ; i++) buff[i] = data [_____] MPI_Send(buff,______ , MPI_FLOAT,______ ,______ ,______ ); 3、下面是PVM环境下的hello程序,它是一个host/node程序,试分析其工作过程。 //*PVM主机/节点编程的hello代码段*// /*host程序hello.c*/ #include <stdio.h> #include “pvm3.h” main() { int cc, tid; char buf[100]; printf(“i’m t%x \n”, pvm_myid()); cc=pvm_spwan(“hello_other”, (char **)0, 0, “”, 1, &tid); if (cc = = 1) { cc=pvm_recv(-1, -1); pvm_bufinfo(cc, (int *)0, (int *)0, &tid); pvm_upkstr(buf); printf(”from t%x: %s \n”, tid, buf); } else printf(“can’t start hello_other \n”); pvm_exit(); } /*node程序hello_other.c*/ #include “pvm3.h” #include “string.h” main() { int ptid; char buf[100]; ptid=pvm_parent(); strcpy(buf, “hello, world from”); gethostname(buf+strlen(buf), 64); pvm_initsend(PvmDataDefault); pvm_pkstr(buf); pvm_send(ptid, 1); pvm_exit(); exit(0); } 4、计算可以通过MPI程序。为了加深读者对MPI的学习和理解,下面给出用FORTRAN 90语言的实现版本。试分析其工作过程。 //*计算的MPI(F90)编程代码段*// program main use mpi double precision PI25DT parameter (PI25DT=3.141592653589793238462643d0) double precision mypi, pi, h, sum, x, f, a integer n, myid, numprocs, i, rc ! function to integrate f(a) = 4.d0/(1.d0+a*a) call MPI_INIT(ierr) call MPI_COMM_RANK(MPI_COMM_WORLD, myid, ierr) call MPI_COMM_SIZE(MPI_COMM_WORLD, numprocs, ierr) print *, ‘process’, myid, ‘of’, numprocs, ‘is alive’ sizetype=1 sumtype=2 do if (myid.eq.0) then write(6, 98) format(‘Enter the number of intervals: (0 quit)’) read(5, 99)n format(i10) endif call MPI_BCAST(n, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr) ! check for quit signal if (n.le.0) exit ! calculate the interval size h=1.0d0/n sum=0.0d0 do i=myid+1, n, numprocs x=h*(dble(i)-0.5d0) sum=sum+f(x) enddo mypi=h*sum ! collect all the partial sums call MPI_REDUCE(mypi, pi, 1, MPI_DOUBLE_PRECISION, MPI_SUM, 0, & MPI_COMM_WORLD, ierr) ! process 0 prints the answer if (myid.eq.0) then write (6, 97) pi, abs(pi-PI25DT) format (‘pi is approximatetly :’, F18.16, & ‘Error is: ’, F18.16) endif enddo call MPI_FINALIZE(rc) stop end 5、Fortran 90计算的程序如下:参照它试写出计算的HPF程序;并将两者加以比较。 //*计算 Fortran 90编程代码段*// INTEGER, PARAM\ETER::N=131072 INTEGER, PARAMETER::LONG=SELECTED_REAL_KIND(13,99) REAL(KIND=LONG)PI, WIDTH INTEGER, DIMENSION(N)::ID REAL(KIND=LONG), DIMENSION(N)::X,Y WIDTH=1.0_LONG/N ID=(/(I,I=1,N)/) X=(ID-0.5)*WIDTH Y=4.0/(1.0+X*X) PI=SUM(Y)*WIDTH FORMAT(“ESTIMATION OF PI WITH”, 16, & “INTERVALS IS”, F14, 12) PRINT 10,N,PI END