MPI学习(二)-非阻塞通信程序(无缓冲)

MPI-非阻塞通信程序(无缓冲)

非阻塞通信程序(无缓冲)是由MPI中的Isend和Ireceive来表示的,即异步通信。在这种情况下,发送进程发布一条“发送授权请求”(挂起的消息)的消息,并继续其程序的执行。当接收进程发布一个“同意发送”许可指令时,数据传输就启动了。所有的这些机制都是通过操作系统的信号进行内部管理的。当数据传输完成时,检查状态并指示进程是否可以安全地进行读/写数据。 需要注意的是原语MPI_Wait(&request,&status)等到数据传输完成(或中断后),使用一个成为status的状态变量来指示数据传输是否已经成功。

相关的MPI原语

1
2
int MPI_Isend(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_comm comm, MPI_Request *req)
int MPI_Irecv(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Request *req)

MPI_Request结构中经常使用的:当*req操作完成时返回 *flag = 1,否则返回 0。

原语MPI_Wait一直等到*req所执行的操作完成。

1
int MPI_Wait(MPI_Request *req, MPI_Status *status)

程序运行平台

北京超级云计算中心A3分区

环境变量

mpi/intel/2017.5

编译指令

mpicc mpi002.cpp -o mpi002

运行指令

mpirun -np 10 ./mpi002(本地提交,采取10个进程)

程序源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include <math.h>
int main(int argc,char **argv)
{
int myid, numprocs;
int tag,source,destination,count;
int buffer;
MPI_Status status;
MPI_Request request;
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
MPI_Comm_rank(MPI_COMM_WORLD,&myid);
tag =2021; /* any integer to tag messages */
source = 0;
count = 1;
if(myid != source )
{
buffer =2077;
//其他进程向0号进程发送消息
MPI_Isend(&buffer,count,MPI_INT,source,tag,MPI_COMM_WORLD,&request);
MPI_Wait(&request,&status);
printf("processor %d send %d to processor %d\n",myid,buffer,source);
}

if(myid == source )
{
//0号进程接收来自其他进程的消息
for(int i=1;i<numprocs;i++)
{
MPI_Irecv(&buffer,count,MPI_INT,i,tag,MPI_COMM_WORLD,&request);
MPI_Wait(&request,&status);
printf("processor %d received %d from processor %d \n",myid,buffer,i);
}

}

MPI_Finalize();
return 0;
}

程序输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
processor 2 send 2077 to processor 0
processor 3 send 2077 to processor 0
processor 5 send 2077 to processor 0
processor 6 send 2077 to processor 0
processor 7 send 2077 to processor 0
processor 8 send 2077 to processor 0
processor 9 send 2077 to processor 0
processor 4 send 2077 to processor 0
processor 1 send 2077 to processor 0
processor 0 received 2077 from processor 1
processor 0 received 2077 from processor 2
processor 0 received 2077 from processor 3
processor 0 received 2077 from processor 4
processor 0 received 2077 from processor 5
processor 0 received 2077 from processor 6
processor 0 received 2077 from processor 7
processor 0 received 2077 from processor 8
processor 0 received 2077 from processor 9