MPI知识点

2022年12月10日 下午2:57 语言学习 ,

在本文之前,已经总结过了其他两类知识点,这里再补充其他所有的来完成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_SendMPI_Revctag一致,sourcedest要相互对应

消息

  • 信封:<源/目,标识,通信域>

  • 数据:<起始地址,数据个数,数据类型>

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_WaitMPI_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,其他全部一致

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注