例2中,每个进程既接收又发送数据,可以利用MPI_Sendrecv函数进行简化,此例和例2功能完全相同,首先看MPI_Sendrecv的用法
代码如下:
MPI_Sendrecv(
void *sendbuf //initial address of send buffer
int sendcount //number of entries to send
MPI_Datatype sendtype //type of entries in send buffer
int dest //rank of destination
int sendtag //send tag
void *recvbuf //initial address of receive buffer
int recvcount //max number of entries to receive
MPI_Datatype recvtype //type of entries in receive buffer
int source //rank of source
int recvtag //receive tag
MPI_Comm comm //group communicator
MPI_Status status //return status;
Note there is compatibility between send-receive and normal sends and receives. A message sent by a send-receive can be received by a regular receive or probed by a regular probe, and a send-receive can receive a message sent by a regular send. MPI_Sendrecv excutes a blocking send and receive operation. both the sent and the receive use the same communicator, but have distinct tag argument. the send buffer and receive buffers must be disjoint, and may have different lengths and datatypes.
Simply speaking: MPI_Sendrecv can replace a pair of consecutive send and receive calls originating from a single process.
Example:
!--Exchange messages
tag1=1
tag2=2
if (myid == 0){
MPI_Sendrecv(a,1,mpi_real,1,tag1,
& b,1,mpi_real,1,tag2,
& MPI_COMM_WORLD, status) //Rank 0 send message to 1 and receive message from 1 simultaneously.
}
else if (myid == 1) {
MPI_Sendrecv(b,1,mpi_real,0,tag2,
& a,1,mpi_real,0,tag1,
& MPI_COMM_WORLD,status)Rank 1 send message to 0 and receive message from 0 simultaneously.
}
现在来看一个更复杂一点的例子:设4个进程,每个进程上有四个数组,所有数组初始值等于进程号。然后每个进程和它相邻的两个进程交换数据。具体来说,
For Rank=0:
A0={0},A1={0},A2={0},A3={0};
For Rank=1:
A0={1},A1={1},A2={1},A3={1};
For Rank=2:
A0={2},A1={2},A2={2},A3={2};
For Rank=3:
A0={3},A1={3},A2={3},A3={3};
然后进程i发送A0和A1到i+1和i-1;并且接收i-1和i+1发送的数据存储在A2和A3.
代码如下:
#include<stdio.h>
#include "mpi.h"
#include <cstdio>