非阻塞通信的一般概念 讲解: 由于通信经常需要较长的时间,在阻塞通信还没有结束的时候,处理机只能等待,这样就浪费了处理机的计算资源。一种常见的技术就是设法使计算与通信重叠,非阻塞通信可以实现这一目的。非阻塞通信主要用于计算和通信的重叠,从而提高整个程序执行的效率,此外,非阻塞通信还可以实现一些特殊的控制功能。
对于非阻塞通信,不必等到通信操作完全完成便可以返回,该通信操作可以交给特定的通信硬件去完成,在该通信硬件完成该通信操作的同时,处理机可以同时进行计算操作,这样便实现了计算与通信的重叠。通过计算与通信的重叠,可以大大提高程序执行的效率。这一方法和通过异步I/O实现I/O与计算的重叠思路是完全一样的。
当然,由于当非阻塞通信调用返回时一般该通信操作还没有完成,因此对于非阻塞的发送操作,发送缓冲区必须等到发送完成后才能释放,这样便需要引入新的手段(非阻塞通信完成对象)让程序员知道什么时候该消息已成功发送;同样,对于非阻塞的接收操作,该调用返回后并不意味着接收消息已全部到达,必须等到消息到达后才可以引用接收到的消息数据。
对于阻塞通信,只需要一个调用函数即可以完成,但是对于非阻塞通信,一般需要两个调用函数,首先是非阻塞通信的"启动",但启动并不意味着该通信过程的完成,因此,为了保证通信的完成,还必须调用与该通信相联系的通信"完成"调用接口,通信完成调用才真正将非阻塞通信完成。
标准非阻塞发送 MPI_ISEND(buf, count, datatype, dest, tag,
comm, request) INbuf发送缓冲区的起始地址(可选数据类型) INcount发送数据的个数(整型)
INdatatype 发送数据的数据类型(句柄) INdest 目的进程号(整型) INtag消息标志(整型)
INcomm 通信域(句柄) OUT request返回的非阻塞通信对象(句柄) int MPI_Isend(void*
buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm,
MPI_Request *request) MPI_ISEND(BUF, COUNT, DATATYPE, DEST, TAG, COMM, REQUEST,
IERROR) <type>BUF(*) INTEGER COUNT, DATATYPE, DEST, TAG, COMM,
REQUEST, IERROR 讲解: MPI_ISEND的功能是启动一个标准的非阻塞发送操作,它调用后立即返回。MPI_ISEND的调用返回并不意味着消息已经成功发送,它只表示该消息可以被发送。和阻塞发送调用相比,它多了一个参数request,这一参数是一个用来描述非阻塞通信状况的对象,这里不妨称之为"非阻塞通信对象",通过对这一对象的查询,就可以知道与之相应的非阻塞发送是否完成。在后面将介绍如何对这一对象进行查询。 标准非阻塞接收
MPI_IRECV(buf, count, datatype, source, tag, comm, request)
OUTbuf接收缓冲区的起始地址(可选数据类型) IN count接收数据的最大个数(整型) IN
datatype 每个数据的数据类型(句柄) IN source 源进程标识(整型) IN tag消息标志(整型)
IN comm 通信域(句柄) OUTrequest非阻塞通信对象(句柄) int MPI_Irecv(void*
buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm,
MPI_Request *request) MPI_IRECV(BUF, COUNT, DATATYPE, SOURCE, TAG, COMM, REQUEST,
IERROR) <type>BUF(*) INTEGER COUNT, DATATYPE, SOURCE, TAG,
COMM, REQUEST, IERROR 讲解: MPI_IRECV的功能是启动一个标准的非阻塞接收操作,它调用后立即返回。MPI_IRECV调用的返回并不意味着已经接收到了相应的消息,它只表示符合要求的消息可以被接收。和阻塞接收调用相比,它多了一个参数request,这一参数的功能和非阻塞发送一样,只不过在这里是用来描述非阻塞接收的完成状况,通过对这一对象的查询,就可以知道与之相应的非阻塞接收是否完成。
|