MPI_Bcast会导致数据不确定性问题吗?

时间:2016-04-27 04:30:45

标签: mpi

如果不同的进程向某个通信器组中的其他进程广播不同的值,会发生什么?

以两个进程运行以下程序为例,

int rank, size;
int x;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
if (rank == 0)
{
    x = 0;
    MPI_Bcast(&x, 1, MPI_INT, 0, MPI_COMM_WORLD);
}
else if (rank==1)
{
    x = 1;
    MPI_Bcast(&x, 1, MPI_INT, 1, MPI_COMM_WORLD);
}
cout << "Process " << rank << "'s value is:" << x << endl;
MPI_Finalize();

我认为在节目结束时印刷结果可能会有不同的可能性。如果进程0比进程1运行得快,它将比进程1更早地广播它的值,因此进程1在开始广播其值时将与进程0具有相同的值,因此使得x的打印值都为0.但是如果过程0比过程1运行得慢,过程0将具有与过程1相同的值,最后为1。我所描述的实际上是否会发生?

2 个答案:

答案 0 :(得分:1)

我认为您不太了解MPI_Bcast功能。实际上,MPI_Bcast是一种MPI集体通信方法,其中属于某个通信器的每个进程都需要涉及。因此,对于MPI_Bcast的功能,不仅发送要广播的数据的进程,而且接收广播数据的进程需要同步调用该功能以实现所有参与进程之间的数据广播的目标。

在您的给定程序中,尤其是这一部分:

parameter RAM_WIDTH = <ram_width>;
parameter RAM_ADDR_BITS = <ram_addr_bits>;

(* RAM_STYLE="{AUTO | BLOCK |  BLOCK_POWER1 | BLOCK_POWER2}" *)
reg [RAM_WIDTH-1:0] <ram_name> [(2**RAM_ADDR_BITS)-1:0];
reg [RAM_WIDTH-1:0] <output_dataB>;

<reg_or_wire> [RAM_ADDR_BITS-1:0] <addressA>, <addressB>;
<reg_or_wire> [RAM_WIDTH-1:0] <input_dataA>;

//  The forllowing code is only necessary if you wish to initialize the RAM 
//  contents via an external file (use $readmemb for binary data)
initial
   $readmemh("<data_file_name>", <ram_name>, <begin_address>, <end_address>);

always @(posedge <clockA>)
   if (<enableA>)
      if (<write_enableA>)
         <ram_name>[<addressA>] <= <input_dataA>;

always @(posedge <clockB>)
   if (<enableB>)
      <output_dataB> <= <ram_name>[<addressB>];

我认为您打算让等级为0的进程(进程0)将其x值广播到其他进程,但在您的代码中,只有进程0在您使用if-else段时调用MPI_Bcast函数。那么其他流程做什么呢?对于等级为1(进程1)的进程,它不调用进程0调用的相同MPI_Bcast函数,尽管它调用另一个MPI_Bcast函数来广播其x值(root的参数在这两个MPI_Bcast函数之间是不同的)因为如果只有进程0调用MPI_Bcast函数,它只是实际上只将x的值广播到其自身,并且存储在其他进程中的x的值根本不会受到影响。此过程与进程1的条件相同。因此,在程序中,每个进程的x的打印值应与最初分配时的打印值相同,并且不会出现数据不确定性问题。

答案 1 :(得分:1)

MPI_Bcast主要用于排名0 [root]可以计算值并广播它们,所以每个人都以相同的值开头。

以下是有效用法:

int x;

// not all ranks may get the same time value ...
srand(time(NULL));

// so we must get the value once ...
if (rank == 0)
    x = rand();

// and broadcast it here ...
MPI_Bcast(&x,1,MPI_INT,0,MPI_COMM_WORLD);

请注意与您的使用情况的区别。 相同 MPI_Bcast调用所有排名。根将执行发送,其他人将执行recv。