默认情况下,这个 Hello World 程序的输出是不确定的。但是可以强制该程序按顺序输出 Hello World,即通过强制 MPI 进程的顺序执行顺序。
说明:【假设你熟悉SPMD编程模型】我们来看看这个程序的执行顺序。
Step 1:Rank 0 的进程首先到达 print 语句,并得到输出通道进行打印。所有其他进程将进入else-if
并且必须在Recv
函数调用处等待。注意:Recv
是一个阻塞调用,需要一个匹配的Send
. 请参考完整的MPI 教程以获得全面的解释!
步骤 2:Rank 0 的进程将向 Rank 1 (rank+1) 的进程发送消息。Recv
现在 Rank 1 进程在发布匹配时退出阻塞Send
,并将获得下一轮打印输出。之后,它会向下一个进程(rank+1)发送一条消息,让它轮流打印。
下一步:在每一步,一个进程else-if
都会得到一个匹配Send
,并会从阻塞中出来Recv
并打印 Hello World 并向下一个 rank 发送消息以允许它打印。最后,最后一个else
语句是最后一个工作人员打印输出并且不发送消息的极端情况。之后执行完成。
int[] datalist = new int[8];
MPI.Init(args);
int rank = MPI.COMM_WORLD.Rank();
int size = MPI.COMM_WORLD.Size();
int buff[] = new int [1];
buff[0] = rank;
int tag = 1001;
if (rank == 0){
System.out.println("Hello World from <"+rank+"> of total "+size+" processes");
MPI.COMM_WORLD.Send(buff, 0, 1, MPI.INT, rank+1, tag);
}
else if (rank < size-1){
MPI.COMM_WORLD.Recv(buff, 0, 1, MPI.INT, rank-1, tag);
System.out.println("Hello World from <"+rank+"> of total "+size+" processes");
MPI.COMM_WORLD.Send(buff, 0, 1, MPI.INT, rank+1, tag);
}
else{
MPI.COMM_WORLD.Recv(buff, 0, 1, MPI.INT, rank-1, tag);
System.out.println("Hello World from <"+rank+"> of total "+size+" processes");
}
MPI.Finalize();
对于 4 个进程,输出将始终为:
Hello World from <0> of total 4 processes
Hello World from <1> of total 4 processes
Hello World from <2> of total 4 processes
Hello World from <3> of total 4 processes