在MPI中,MPI_Bcast
纯粹是一个便利功能还是使用它而不是仅仅循环所有等级并向所有等级发送相同的消息有效率优势?
基本原理:MPI_Bcast
向所有人(包括根)发送消息的行为对我来说不方便,所以除非有充分的理由,否则我宁愿不使用它,或者可以做到将消息发送给root。
答案 0 :(得分:8)
使用MPI_Bcast肯定比滚动自己更有效。在所有MPI实现中已经做了很多工作,以根据消息大小和通信架构等因素优化集合操作。
例如,MPI_Bcast in MPICH2 would use a different algorithm depending on the size of the message。对于短消息,二叉树用于最小化处理负载和延迟。对于长消息,它实现为二进制树分散,后跟全部集合。
此外,HPC供应商通常提供有效利用底层互连的MPI实现,尤其是集体操作。例如,可以使用hardware supported multicast scheme或use bespoke algorithms that can take advantage of the existing interconnects。
答案 1 :(得分:3)
集体沟通比滚动自己更快 。所有MPI的实施都花费了大量时间来完成这些例程。
如果你经常想要集体类型的东西,但只是在一部分任务上,那么你可能想要创建自己的子传播者并在这些传播者身上使用BCAST等。
答案 2 :(得分:2)
MPI_Bcast
将消息从一个进程(“root”)发送到所有其他。它可能比仅仅循环遍历所有进程要快一点。例如,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
答案 3 :(得分:2)
答案是,在一般情况下,MPI_Bcast可能比循环更快。通常,MPI集合在各种消息大小,通信大小和特定的排名布局上进行了优化。
也就是说,有可能在特定的消息大小,通信大小和排名布局中击败集体。例如,非阻塞点对点调用(例如,ISend和Recv / IRecv)的循环可能更快......但可能仅在几个特定的消息大小,通信大小和排名布局上。
如果您编码的特定算法需要Bcast模式(例如,所有排名从根获取相同的数据有效负载),则使用Bcast集合。一般来说,通过滚动自己的“集体替代”来增加并发症是不值得的。
如果算法需要一些其他的消息模式,而Bcast只是部分适合......那么可能值得推出自己的......但我个人认为这个标准相当高。