在本文之前,已经总结过了其他两类知识点,这里再补充其他所有的来完成MPI知识点
MPI数据类型 - CarryNotKarry
MPI阻塞与非阻塞通信 - CarryNotKarry
函数
基础函数
int MPI_Abort(MPI_Comm comm, int errorcode)
(终止)
终止MPI程序时执行,errorcode将被作为进程的退出码返回给系统,MPI系统会终止comm通信器中的所有进程。
int MPI_Get_processor_name(char *name, int *resultlen)
(获取处理器名称)
resultlen存放返回名字所占字节,name不少于MPI_MAX_PROCESSOR_NAME
个字节的存储空间。
double MPI_Wtime
(获取时间)
通讯函数
MPI_Alltoall
(全散发收集)
MPI_Bcast
(广播)
笔记
阻塞式点对点通信
阻塞式消息发送
int MPI_Send(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)
buf
首地址count
发送消息数组元素个数(不是字节数)datatype
发送消息数据类型。可以是原始数据类型,或者是自定义,如MPI_INT
dest
接收消息的进程编号。取值范围是$[0,np-1]$,或者是MPI_PROC_NULL
tag
消息标签,用来区分消息。comm
:通信器,一般是MPI_COMM_WORLD
阻塞式消息接收
int MPI_Recv(void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status)
buf
首地址count
接收消息数组元素的最大个数,接收缓冲区的大小,表示上界,具体接受长度可以用MPI_Get_count
获得datatype
接收消息数据类型source
发送消息的进程编号tag
消息标签,取值范围是[0, MPI_TAG_UB]或者MPI_ANY_TAG
status
接收消息时返回的状态
MPI_Send
和MPI_Revc
的tag
一致,source
和dest
要相互对应
消息
- 信封:<源/目,标识,通信域>
-
数据:<起始地址,数据个数,数据类型>
status
typedef struct {
int count;
int cancelled;
int MPI_SOURCE; 消息源地址
int MPI_TAG; 消息标号
int MPI_ERROR; 接收操作的错误码
}MPI_Status;
使用前需要申请空间MPI_Status status
,可以使用后面3个域
标准阻塞式通信
缓存够则不依赖
是否对发送数据进行缓存,由MPI系统决定,而非程序员
任意源进程:MPI_ANY_SOURCE
任意标号:MPI_ANY_TAG
其他阻塞式点对点通信函数
捆绑发送和接收
int MPI_Sendrecv(const void *sendbuf, int sendcount, MPI_Datatype sendtype, int dest, int sendtag, void *recvbuf, int recvcount, MPI_Datatype recvtype, int source, int recvtag, MPI_Comm comm, MPI_Status *status)
sendbuf
是要发送的数据的指针。sendcount
是要发送的数据的数量。sendtype
是要发送的数据的数据类型。dest
是要发送数据的目标进程的编号。sendtag
是要发送的数据的标签。recvbuf
是接收数据的缓冲区的指针。recvcount
是接收数据的数量。recvtype
是接收数据的数据类型。source
是要接收数据的源进程的编号。recvtag
是要接收的数据的标签。comm
是要使用的通信器。status
是接收操作的状态。
语义上等同于一个发送和一个接收操作结合,但此函数可以有效避免在单独发送和接收操作过程中,由于调用次序不当而造成的死锁
。MPI系统会优化通信次序,从而最大限度避免错误发生。
捆绑发送和接收,收发使用同一缓存区
MPI_Sendrecv_replace
阻塞式
通信模式 | 发送 | 接收 |
---|---|---|
标准通信模式 | MPI_SEND |
MPI_RECV |
缓存通信模式 | MPI_BSEND |
|
同步通信模式 | MPI_SSEND |
|
就绪通信模式 | MPI_RSEND |
- 四个函数拥有完全一样的入口参数,共用一个标准的消息接收函数。
缓存消息发送函数MPI_Bsend
异步,Bsend函数可以快速发送消息,不会等待消息发送完成,函数可能会在发送消息之前退出,消息可能会丢失,所以需要使用MPI_Buffer_attach
函数来进行缓冲区申请提交,附加一个缓冲区,用来存储消息。
同步消息发送函数MPI_Ssend
同步,等待消息发送完成才会返回,这样更安全,但是也会更慢。
就绪消息发送函数MPI_Rsend
该函数要求接收方已经准备好接收消息。发送消息时会检查接收方是否已经准备好接收消息,这使得非常快,但是问题是若没有准备好则会立即返回,不会等待其准备好,所以可能会导致消息的丢失。
非阻塞式
非阻塞式发送
int MPI_Isend(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request)
提交了一个消息发送请求,并立即返回,MPI系统会在后台完成消息发送
非阻塞式接收
int MPI_Irecv(void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Request *request)
提交了一个消息接收请求,并立即返回,MPI系统会在后台完成消息接收
等待和检测
- 一个:
MPI_Wait
,MPI_Test
-
一组中某一个:
MPI_Waitany, MPI_Testany
-
一组中全部:
MPI_Waitall, MPI_Testall
-
一组中部分:
MPI_Waitsome, MPI_Testsome
通信请求的释放
- 阻塞型:
MPI_Request_free(MPI_Request *request)
调用MPI_Wait/Test可间接释放完成的通信请求,此函数则直接释放通信请求及所占内存空间
如果通信尚未完成,则阻塞等待完成后返回
- 非阻塞型:
MPI_Cancel(MPI_Request *request)
若相应非阻塞通信已经开始,它会正常完成,不受影响;若没有开始,则释放通信占用资源,该通信被取消
聚合通信
MPI_Bcast
(广播)阻塞式广播
int MPI_Bcast(void *buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm)
MPI_Gather
(收集)
int MPI_Gather(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)
MPI_Gatherv
每个进程发送的数据个数不同。
MPI_Allgather
(全收集)
MPI_Allgatherv
MPI_Scatter
(散发)
int MPI_Scatter(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)
MPI_Scatterv
MPI_Alltoall
(全散发收集)
收集和散发总结
MPI_Reduce
归约
int MPI_Reduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm)
MPI_Allreduce
全归约
只比MPI_Reduce
少一个参数root
,其他全部一致
文章评论