MPI - 无限期发送和回收

时间:2011-02-19 16:46:50

标签: c mpi

如果我使用阻止发送和recv(MPI_send()MPI_recv()),如何使两个操作无限期?就像他们重复一遍一样?

示例代码:

MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD,&numtasks);
MPI_Comm_rank (MPI_COMM_WORLD,&rank);
if(rank==0){
  rc=MPI_Send(msg,1,MPI_CHAR,1,1,MPI_COMM_WORLD);
  rc=MPI_Recv(msg,1,MPI_CHAR,1,1,MPI_COMM_WORLD,&status);
}else{
  rc=MPI_Recv(msg,1,MPI_CHAR,0,0,MPI_COMM_WORLD,&status);
  rc=MPI_Send(msg,1,MPI_CHAR,0,0,MPI_COMM_WORLD);

}

我试图放在if(rank==0) -> while(1)之前,它完成了这项工作,但我看到有几个发送,然后几个接收,我想要它 - 发送(0),接收(1),发送(1) ),收到(0)。

2 个答案:

答案 0 :(得分:3)

您可以使用 MPI_Sendrecv 轻松编码一组发送 - 接收操作:

int MPI_Sendrecv(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)

正如您所看到的,它只是MPI_Send和MPI_Recv的精简版本,但当所有进程需要发送 时,它会很方便某事。

以下代码适用于任何数量的流程(您可以根据需要进行调整):

CODE UPDATE#1(使用MPI_Sendrecv)

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

int main (int argc, char *argv[])
{
    int size, rank, value, next, prev, sendval, recval;
    double t0, t;

    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    value = 5;

    if (size > 1)
    {
        next = (rank + 1)% size;
        prev = (size+rank - 1)% size;

        sendval = value + rank;

        for (;;) 
        {
            t0 = MPI_Wtime();
            MPI_Sendrecv(&sendval, 1, MPI_INT, next, 1, &recval, 1, MPI_INT, prev, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
            t = MPI_Wtime();

            fprintf(stdout, "[%d of %d]: Sended %d to process %d, Received %d from process %d (MPI_SendRecv Time: %f)\n",rank, size-1, sendval, next, recval, prev, (t - t0));
        }

    }

    MPI_Finalize();
    return 0;
}

CODE UPDATE#2(使用单独的MPI_Send / MPI_Recv)

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

int main (int argc, char *argv[])
{
    int size, rank, value, next, prev, sendval, recval;
    double s0, s, r, r0;

    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    value = 5;

    if (size > 1)
    {
        next = (rank + 1)% size;
        prev = (size+rank - 1)% size;

        sendval = value + rank;

        for (;;) 
        {
            s0 = MPI_Wtime();
            MPI_Send(&sendval, 1, MPI_INT, next, 1, MPI_COMM_WORLD);
            s = MPI_Wtime();
            fprintf(stdout, "[%d of %d]: Sended %d to process %d (MPI_Send Time: %f)\n", rank, size-1, sendval, next, s-s0);

            r0 = MPI_Wtime();
            MPI_Recv(&recval, 1, MPI_INT, prev, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
            r = MPI_Wtime();
            fprintf(stdout, "[%d of %d]: Received %d from process %d (MPI_Recv Time: %f)\n", rank, size-1, recval, prev, r-r0);

        }

    }
        MPI_Finalize();
    return 0;
}

运行示例

mpicc -o sendrecv sendrecv.c
mpirun -n 2 sendrecv

[0 of 1]: Sended 5 to process 1, Received 6 from process 1 (MPI_SendRecv Time: 0.000121)
[1 of 1]: Sended 6 to process 0, Received 5 from process 0 (MPI_SendRecv Time: 0.000068)
...

答案 1 :(得分:0)

如果不至少看到代码的基本布局,就不可能给出准确的答案。通常,您将发送和接收操作置于无限循环内。或者,如果你很难获得最佳的沟通成本(或只是冒险冒险),你可以使用persistent Send and Receive