第十四章 分布存储系统并行编程
习题例题:
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