P2P Blocking

来源:互联网 发布:java启动参数配置 编辑:程序博客网 时间:2024/04/28 07:30

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:2202.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 = 1rankID = 1, sourceRankID = 0, sum = 1, receive char = 0, tag = 1my rankID = 3, I didn't participate in P2P communicationmy 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个数据。










原创粉丝点击