MPI发送/接收数百万条消息

时间:2014-01-29 13:16:52

标签: mpi

对于大于0的proc,我有超过NT(数百万次迭代)的循环。对于每次迭代,120字节的消息被发送到proc 0,proc 0接收它们(对于proc 0,我在NT上有相同的循环)。

我希望proc 0接收它们,所以我可以将它们存储在数组nhdr1中。

问题是proc 0没有正确接收消息,我在数组nhdr中经常有0个值。

如何修改代码,以便在发送消息时以相同的顺序接收消息?

[...]
    if (rank == 0) {

        nhdr  = malloc((unsigned long)15*sizeof(*nhdr));
        nhdr1 = malloc((unsigned long)NN*15*sizeof(*nhdr1));

        itr = 0;
        jnode = 1;

        for (l=0; l<NT; l++) {

            MPI_Recv(nhdr, 15, MPI_LONG, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);

            if (l == status.MPI_TAG) {
                for (i=0; i<nkeys; i++)
                    nhdr1[itr*15+i] = nhdr[i];
            }

            itr++;

            if (itr == NN) {
                ipos = (unsigned long)(jnode-1)*NN*15*sizeof(*nhdr1);

                fseek(ismfh, ipos, SEEK_SET);
                nwrite += fwrite(nhdr1, sizeof(*nhdr1), NN*15, ismfh);

                itr = 0;
                jnode++;
            }
        }

        free(nhdr);
        free(nhdr1);

    } else {

        nhdr = malloc(15*sizeof(*nhdr));

        irecmin = (rank-1)*NN+1;
        irecmax = rank*NN;

        for (l=0; l<NT; l++) {
            if (jrec[l] >= irecmin && jrec[l] <= irecmax) {

                indx1 = (unsigned long)(jrec[l]-irecmin) * 15;

                for (i=0; i<15; i++)
                    nhdr[i] = nhdr1[indx1+i]; // nhdr1 is allocated before for rank>0!

                MPI_Send(nhdr, 15, MPI_LONG, 0, l, MPI_COMM_WORLD);
            }
        }

        free(nhdr);

    }

3 个答案:

答案 0 :(得分:4)

无法保证您的邮件按照从不同级别发送的顺序到达排名0。例如,如果您有这样的场景(S1表示发送消息1):

rank 0 ----------------
rank 1 ---S1------S3---
rank 2 ------S2------S4

无法保证消息将按顺序S1,S2,S3,S4到达等级0。 MPI做出的唯一保证是,在具有相同标签(您正在做的)的同一个通信器上发送的每个等级的消息将按照它们发送的相同顺序到达。这意味着生成的订单可能是:

S1, S2, S3, S4

或者可能是:

S1, S3, S2, S4

或:

S2, S1, S3, S4

......等等。

对于大多数应用程序来说,这并不重要。重要的顺序是逻辑顺序,而不是实时排序。您可能需要再次查看您的应用程序,并确保无法放松您的要求。

答案 1 :(得分:1)

“你收到的邮件是按照相同的顺序收到的”是什么意思?

现在在代码中,消息ARE(大致)以实际发送的顺序接收...但该顺序与排名数无关,或者与其他任何东西无关。有关详细信息,请参阅@Wesley Bland的回复。

如果您的意思是“按排名顺序接收邮件”...那么有几个选项。

首先,像MPI_Gather或MPI_Gatherv这样的集体将是一个“明显”的选择,以确保数据按产生它的等级排序。这仅在每个等级执行相同迭代次数时才有效,并且这些迭代保持大致同步。

其次,您可以删除MPI_ANY_SOURCE,并使用“按顺序”提供的缓冲区发布一组MPI_IRevc。当消息到达时,它将“自动”处于正确的缓冲区位置。对于收到的每条消息,可以使用提供的正确recv缓冲区位置发布新的MPI_Irecv。任何未匹配的MPI_Irecv都需要在作业结束时取消。

答案 2 :(得分:0)

请记住:

  • 来自给定排名的消息按顺序收到
  • 消息在MPI_Recv()
  • 返回的状态结构(status.MPI_SOURCE)中具有原始处理器等级

您可以使用这两个元素将接收到的数据正确放入nhdr1。