P2P Blocking

1. Blocking send / Blocking receive

(1)阻塞发送(blocking send)是指sender把消息放入application buffer后,不能返回继续其他操作。直到这个application buffer可修改后。

这个时刻有两种可能:

(a)异步(asynchronous)阻塞发送:  消息从sender的application buffer被拷入了system buffer,接下来sender就不用阻塞了

(b)同步(synchronous)阻塞发送:通过与receiver握手机制确认消息已经到达了receiver的system buffer或者application buffer,此时sender才解除阻塞

结论:若sender端有system buffer,则(a)异步肯定是首选,这样阻塞的时间要短一些。

(2)阻塞接受(Blocking receive)是指receiver一直阻塞自己,直到消息到达receiver的application buffer(即自己端的变量或者对象所在的内存中有值了)

2. 最简单的函数

MPI_Send (&buf,count,datatype,dest,tag,comm)

Basic blocking send operation. Routine returns only after the application buffer in the sending task is free for reuse. Note that this routine may be implemented differently on different systems. The MPI standard permits the use of a system buffer but does not require it. Some implementations may actually use a synchronous send (discussed below) to implement the basic blocking send.

MPI_Recv (&buf,count,datatype,source,tag,comm,&status)

Receive a message and block until the requested data is available in the application buffer in the receiving task.

3. 举例

#include"mpi.h"
#include<stdio.h>

int main(int argc, char *argv[]){
        int totalNumTasks, rankID, tag = 1;

        MPI_Init(&argc, &argv);
        MPI_Comm_size(MPI_COMM_WORLD, &totalNumTasks);
        MPI_Comm_rank(MPI_COMM_WORLD, &rankID);

        int count = 1;
        if(rankID == 0){
                char outMsg = '0';
                int dest = 1;
                int rt1 = MPI_Send(&outMsg, count, MPI_CHAR, dest, tag, MPI_COMM_WORLD);

                int source = 1;
                char inMsg;
                MPI_Status status;
                int rt2 = MPI_Recv(&inMsg, count, MPI_CHAR, source, tag, MPI_COMM_WORLD, &status);
                //==============================================================        
                int sum;
                MPI_Get_count(&status, MPI_CHAR, &sum);
                printf("rankID = %d, sourceRankID = %d, sum = %d, receive char = %c, tag = %d\n",
                        rankID, status.MPI_SOURCE, sum, inMsg, status.MPI_TAG);
        }else if(rankID == 1){
                int dest = 0;
                char outMsg = '1';
                int rt4 = MPI_Send(&outMsg, count, MPI_CHAR, dest, tag, MPI_COMM_WORLD);

                int source = 0;
                char inMsg;
                MPI_Status status;
                int rt3 = MPI_Recv(&inMsg, count, MPI_CHAR, source, tag, MPI_COMM_WORLD, &status);
                //==============================================================        
                int sum;
                MPI_Get_count(&status, MPI_CHAR, &sum);
                printf("rankID = %d, sourceRankID = %d, sum = %d, receive char = %c, tag = %d\n",
                        rankID, status.MPI_SOURCE, sum, inMsg, status.MPI_TAG);
        }else
                printf("my rankID = %d, I didn't participate in P2P communication\n", rankID);

        MPI_Finalize();
        return 0;
}

4. 执行

[amao@amao991 mpi-study]$ cat machinefile 
202.117.10.37:2
202.117.10.50:1
[amao@amao991 mpi-study]$ mpicc p2pBlocking.c 
[amao@amao991 mpi-study]$ mpiexec -n 4 -f machinefile ./a.out 
rankID = 0, sourceRankID = 1, sum = 1, receive char = 1, tag = 1
rankID = 1, sourceRankID = 0, sum = 1, receive char = 0, tag = 1
my rankID = 3, I didn't participate in P2P communication
my rankID = 2, I didn't participate in P2P communication

5. 总结

(1)本例中proces0和process1同时担任sender和receiver的角色,如果需要更简单一些,只要一个发,一个接受就可以了

(2)本利中MPI_Send和MPI_Recv都是阻塞的,因此函数调用后,进程不能去干别的事情(即使不访问发送数据所在的内存而访问别的内存也不行),要乖乖等待一段时间。

(3)接受方可以通过MPI_Get_count函数从&status中获取接受了sum个数据。










  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值