5

在 MPI 中,MPI_Bcast纯粹是一种便利功能,还是使用它而不是仅仅循环所有等级并向所有等级发送相同的消息有效率优势?

理由: MPI_Bcast将消息发送给包括root在内的所有人的行为对我来说很不方便,所以除非有充分的理由,否则我宁愿不使用它,或者可以不向root发送消息。

4

4 回答 4

8

使用 MPI_Bcast 肯定会比自己滚动更有效。在所有 MPI 实现中都做了很多工作,以根据消息大小和通信架构等因素优化集体操作。

例如,MPICH2 中的 MPI_Bcast 将根据消息的大小使用不同的算法。对于短消息,使用二叉树来最小化处理负载和延迟。对于长消息,它被实现为一个二叉树散布图,然后是一个 allgather。

此外,HPC 供应商通常会提供 MPI 实现,以有效利用底层互连,尤其是对于集体操作。例如,可以使用硬件支持的多播方案使用可以利用现有互连的定制算法

于 2011-08-05T17:05:17.260 回答
4

集体沟通可能比滚动自己的沟通要快得多所有的 MPI 实现都花费大量时间来处理这些例程以提高速度。

如果您经常想做集体类型的事情,但只针对一部分任务,那么您可能想要创建自己的子通信器并在这些通信器上使用 BCAST 等。

于 2011-08-05T17:09:11.697 回答
3

MPI_Bcast根据定义,将消息从一个进程(“根”)发送到所有其他进程。它也可能比仅循环所有进程要快一点。例如,该mpich2实现使用二叉树来分发消息。

如果你不想广播到 MPI_COMM_WORLD,但你想定义子组,你可以这样做:

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

#define NPROCS 8

int main(int argc, char **argv)
{
    int rank, new_rank, sendbuf, recvbuf,
    ranks1[4]={0,1,2,3}, ranks2[4]={4,5,6,7};

    MPI_Group orig_group, new_group;
    MPI_Comm new_comm;

    MPI_Init(&argc,&argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    sendbuf = rank;

    /* Extract the original group handle */
    MPI_Comm_group(MPI_COMM_WORLD, &orig_group);

    /* Divide tasks into two groups based on rank */
    if (rank < NPROCS/2) {
        MPI_Group_incl(orig_group, NPROCS/2, ranks1, &new_group);
    } else {
        MPI_Group_incl(orig_group, NPROCS/2, ranks2, &new_group);
    }

    /* Create new communicator and then perform some comm
     * Here, MPI_Allreduce, but you can MPI_Bcast at will
     */
    MPI_Comm_create(MPI_COMM_WORLD, new_group, &new_comm);
    MPI_Allreduce(&sendbuf, &recvbuf, 1, MPI_INT, MPI_SUM, new_comm);
    MPI_Group_rank (new_group, &new_rank);

    printf("rank= %d newrank= %d recvbuf= %d\n", rank, new_rank, recvbuf); 

    MPI_Finalize();
} 

这可能会产生类似于以下输出的内容:

rank= 7 newrank= 3 recvbuf= 22
rank= 0 newrank= 0 recvbuf= 6 
rank= 1 newrank= 1 recvbuf= 6 
rank= 2 newrank= 2 recvbuf= 6 
rank= 6 newrank= 2 recvbuf= 22
rank= 3 newrank= 3 recvbuf= 6
rank= 4 newrank= 0 recvbuf= 22
rank= 5 newrank= 1 recvbuf= 22
于 2011-08-05T17:06:39.200 回答
3

答案是 MPI_Bcast 在一般情况下可能比循环快。通常,MPI 集合针对各种消息大小、通信大小和特定等级布局进行了优化。

也就是说,有可能在特定的消息大小、通信大小和排名布局上击败集体。例如,在非阻塞点对点调用(例如 ISend 和 Recv/IRecv)上的循环可能会更快……但可能仅限于一些特定的消息大小、通信大小和排名布局。

如果您正在编码的特定算法需要 Bcast 模式(例如,所有等级从根获取相同的数据有效负载),则使用 Bcast 集合。一般来说,通过滚动你自己的“集体替代品”来增加复杂性是不值得的。

如果算法需要其他一些消息模式,并且只有部分适合的 Bcast ......那么它可能值得你自己滚动......但我个人将这个标准设置得相当高。

于 2011-08-09T16:16:37.020 回答