Example-3-Using MPI_Sendrecv

例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>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`MPI_Sendrecv` 函数是 MPI 库中的一个消息传递函数,它可以在一个函数调用中完成发送接收操作,因此可以避免死锁等问题。 `MPI_Sendrecv` 函数的原型如下: ``` 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`:接收消息的状态。 该函数的作用是将 `sendbuf` 中的 `sendcount` 个数据按照 `sendtype` 类型发送给进程 `dest`,并从进程 `source` 接收数据到 `recvbuf` 中,数据类型为 `recvtype`,数量为 `recvcount`,接收消息的标签为 `recvtag`,发送消息的标签为 `sendtag`,通信子为 `comm`。 需要注意的是,`MPI_Sendrecv` 函数是一个阻塞函数,也就是说,它会一直等待直到发送接收都完成。在函数返回后,可以通过 `status` 参数来获取接收消息的状态。 下面是一个简单的例子: ```c #include <mpi.h> #include <stdio.h> int main(int argc, char** argv) { int rank, size; int sendbuf, recvbuf; MPI_Status status; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); if (rank == 0) { sendbuf = 123; MPI_Sendrecv(&sendbuf, 1, MPI_INT, 1, 0, &recvbuf, 1, MPI_INT, 1, 1, MPI_COMM_WORLD, &status); printf("Process %d sent %d and received %d\n", rank, sendbuf, recvbuf); } else if (rank == 1) { sendbuf = 456; MPI_Sendrecv(&sendbuf, 1, MPI_INT, 0, 1, &recvbuf, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status); printf("Process %d sent %d and received %d\n", rank, sendbuf, recvbuf); } MPI_Finalize(); return 0; } ``` 上面的代码中,进程 0 向进程 1 发送数据 123,同时接收来自进程 1 的数据。进程 1 向进程 0 发送数据 456,同时接收来自进程 0 的数据。最终输出结果为: ``` Process 0 sent 123 and received 456 Process 1 sent 456 and received 123 ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值