我有一个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广播?(一个节点同时播放三个频道.)
谢谢.
如果我理解你的问题,你希望同时进行逐行广播:
P00 -> P01 & P02
P10 -> P11 & P12
P20 -> P21 & P22
Run Code Online (Sandbox Code Playgroud)
这可以使用子通信器来完成,例如,其中只有来自行0的进程的子通信器,另一个只具有来自行1的进程的子通信器,依此类推.然后,您可以通过MPI_Bcast使用适当的communicator参数调用在每个子通信器中发出同步广播.
如果您首先使用笛卡尔通信器,那么创建行式子通信器非常容易.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);
Run Code Online (Sandbox Code Playgroud)
现在comm_row将包含一个新的子通信器的句柄,该子通信器只会跨越调用进程所在的同一行.现在只需要一次调用即可MPI_Bcast同时执行三个逐行广播:
MPI_Bcast(&data, data_count, MPI_DATATYPE, 0, comm_row);
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为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);
Run Code Online (Sandbox Code Playgroud)
再一次comm_row将包含一个子通信器的句柄,该子通信器只跨越与调用进程相同的行.