Message Passing Interface(MPI)

一 定义

MPI和Openmp是常用的应用在CPU上的并行化框架。

MPI是一个跨语言的通讯协议,用于编写并行计算机。支持点对点和广播。MPI的目标是高性能,大规模性,和可移植性。MPI在今天仍为高性能计算的主要模型。

特点:

  1. A partitioned address space 每个线程只能通过调用api去读取非本地数据。所有的交互(Non-local Memory)都需要协同进行(握手)。

  2. Supports only explicit parallelization 只支持显性的并行化,用户必须明确的规定消息传递的方式。

二 最基本的操作Send & Receive

MPI所有的操作都是基于Send & Receive上进行的。

协议 Protocols For Send/Receive:

 

Blocking Operations

Non-Blocking Operations

Buffered

Sending process returns after data has been copied into communication buffer

Sending process returns after initiating DMA transfer to buffer. This operation may not be completed on return

Non-Buffered

Sending process blocks until matching receive operation has been encountered

None

1)Blocking Non-Buffered Send/Receive:(握手)

Message Passing Interface(MPI)_第1张图片

死锁的发生Deadlocks in Blocking Non-Buffered Operations:

Message Passing Interface(MPI)_第2张图片
P0等待P1的recv,P1又在等待P0的recv,导致无休止的等待。

2) Blocking Buffered Send/Receive:

Message Passing Interface(MPI)_第3张图片

虽会缓解阻塞情况下idle time的情况,但如果buffer存满,依旧需要等待另一方的消耗掉存储的data。recv存满的话会通知sender不要再传了。

死锁的发生(概率很低):

会出现在p0和p1速度差异大,而且恰好都存在如上操作。而且根本原因是,Recv操作会一直阻塞为确保SC(semantic consistency)。

3)Non-Blocking Message Passing:

确保语义安全以后才会返回。通过check-status operation去确保。

Message Passing Interface(MPI)_第4张图片

 

三 Interface

初始化操作:

MPI_Init 只能调用一次。

如何设置rank数? 基于全局最大线程数量,自动设定的。

global environment setting "OMP_NUM_THREADS" for all your MPI processes

MPI_Finalize

MPI的都是建立在recv&send之上的,需要规定门牌号,往哪传,传什么。

1)Communication domain 和 rank (门牌号)

Communication domain:

Communication domain(变量名 MPI_Comm)规定了各个线程允许通信的范围。默认是MPI_COMM_WORLD,包含了所有的线程。可以自定义通信域,一个线程可以属于不同的通信域(存在overlap)。

Message Passing Interface(MPI)_第5张图片

int MPI_Comm_size(MPI_Comm comm, int *size) 返回通信域的线程数

MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm *newcomm)对通信域的重新划分,要求原先通信域的所有线程都要显性的调用该函数去划分。每个线程给自己添加个颜色,API会匹配颜色来进行划分。

Message Passing Interface(MPI)_第6张图片

Code eg:

Message Passing Interface(MPI)_第7张图片

Message Passing Interface(MPI)_第8张图片

Rank:

The MPI_Comm_rank determines the label of the calling process

int MPI_Comm_rank(MPI_Comm comm, int *rank)返回一个整数(0 - 通信域的大小 - 1)

2)send&recv

Blocking:

  • int MPI_Send(void*buf,intcount,MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)

  • int MPI_Recv(void*buf,intcount,MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status)

count: the number of entries in the buffer从buufer中取多少

tag:distinguish different messages对msg标记

Non-Blocking:

  • MPI_Isend(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request)

  • MPI_Irecv(void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Request *request)

非阻塞仅仅是完成请求就直接返回一个request obj,用于MPI_Test和MPI_Wait functionstrack该request是否完成。

3)组通信

Gather & Scatter:

Gather多对一:

MPI_Gather(void *sendbuf, int sendcount, MPI_Datatype senddatatype, void *recvbuf, int recvcount, MPI_Datatype recvdatatype, int target, MPI_Comm comm)

Message Passing Interface(MPI)_第9张图片

每个process传送的data大小和类型必须相同。

Message Passing Interface(MPI)_第10张图片

Scatter(一对多):

Message Passing Interface(MPI)_第11张图片

Broadcast & Reduction:

和上面两个不同的是,gather和scatter是发不同的数据,broadcast和reduction是发送相同数据。

MPI_Bcast(void *buf, int count, MPI_Datatype datatype, int source, MPI_Comm comm)

从域内一个线程发送相同的内容到组内其他所有线程。

Message Passing Interface(MPI)_第12张图片

MPI_Reduce (void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int target, MPI_Comm comm)

需要注意的一点是,reduce包括target在内,全部都要进行reduce操作。

Message Passing Interface(MPI)_第13张图片

Barrier:
MPI_Barrier(MPI_Comm comm)

规定组内所有线程的同步点。

 

你可能感兴趣的:(Message Passing Interface(MPI))