MPI几个同时播出

时间:2012-07-07 03:26:55

标签: mpi broadcast

我有一个2D处理器网格(3 * 3):

P00,P01,P02在R0,P10,P11,P12中,在R1中,P20,P21,P22在R2中。 P * 0在同一台计算机上。所以与P * 1和P * 2相同。

现在我想让R0,R1,R2同时调用MPI_Bcast从P * 0广播到p * 1和P * 2.

我发现当我使用MPI_Bcast时,只需要在一行中播放三倍的时间。

例如,如果我只在R0中调用MPI_Bcast,则需要1.00秒。 但如果我在所有R [0,1,2]中调用三个MPI_Bcast,则总共需要3.00秒。 这意味着MPI_Bcast无法并行工作。

是否有任何方法可以同时播放MPI_Bcast广播? (一个节点同时播放三个频道。)

感谢。

2 个答案:

答案 0 :(得分:5)

如果我理解你的问题,你希望同时进行逐行广播:

P00 -> P01 & P02
P10 -> P11 & P12
P20 -> P21 & P22

这可以使用子通信器完成,例如一个只有第0行的进程,另一个只有第1行的进程,依此类推。然后,您可以通过使用适当的通信器参数调用MPI_Bcast来在每个子通信器中发出同步广播。

如果您首先使用笛卡尔通信器,那么创建行式子通信器非常容易。 MPI为此提供MPI_CART_SUB操作。它的工作原理如下:

// Create a 3x3 non-periodic Cartesian communicator from MPI_COMM_WORLD
int dims[2] = { 3, 3 };
int periods[2] = { 0, 0 };
MPI_Comm comm_cart;

// We do not want MPI to reorder our processes
// That's why we set reorder = 0
MPI_Cart_create(MPI_COMM_WORLD, 2, dims, periods, 0, &comm_cart);

// Split the Cartesian communicator row-wise
int remaindims[2] = { 0, 1 };
MPI_Comm comm_row;

MPI_Cart_sub(comm_cart, remaindims, &comm_row);

现在comm_row将包含一个新的子通信器的句柄,该子通信器只会跨越调用进程所在的同一行。现在只需要一次调用MPI_Bcast就可以同时执行三个行。广播:

MPI_Bcast(&data, data_count, MPI_DATATYPE, 0, comm_row);

这是有效的,因为comm_row返回的MPI_Cart_sub在位于不同行的进程中会有所不同。 0这里是comm_row子通信器中第一个进程的等级,由于拓扑的构建方式,它对应P*0

如果您不使用笛卡尔式通信器而是使用MPI_COMM_WORLD,则可以使用MPI_COMM_SPLIT将世界通信器分成三个行式子通信器。 MPI_COMM_SPLIT使用color来将进程分组到新的子通信器中 - 具有相同color的进程最终位于同一个子通信器中。在您的情况下,color应该等于调用进程所在行的编号。拆分操作也需要key,用于对新子通信器中的进程进行排序。它应该等于调用进程所在的列数,例如:

// Compute grid coordinates based on the rank
int proc_row = rank / 3;
int proc_col = rank % 3;
MPI_Comm comm_row;

MPI_Comm_split(MPI_COMM_WORLD, proc_row, proc_col, &comm_row);

comm_row将再次包含一个子通信器的句柄,该子通信器只跨越与调用进程相同的行。

答案 1 :(得分:1)

MPI-3.0草案包含一个非阻塞MPI_Ibcast集体。虽然非阻塞集体尚未正式成为标准的一部分,但它们已经在MPICH2和(我认为)OpenMPI中可用。

或者,您可以从单独的线程开始阻止MPI_Bcast调用(我假设R0,R1和R2是不同的传播者)。

第三种可能性(可能或可能不可能)是重组数据,以便只需要一次广播。