MPI_Bcast会不会导致数据不确定的问题?
Could MPI_Bcast lead to the issue of data uncertainty?
如果不同的进程向某个通信者所在组中的其他进程广播不同的值,会发生什么?
以下程序运行以两个进程为例,
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 运行s 比进程 1 快,它会比进程 1 更早广播它的值,因此进程 1 在开始广播其值时将与进程 0 具有相同的值,因此打印出 x 的值两者都是 0。但是,如果进程 0 运行 比进程 1 慢,则进程 0 将具有与进程 1 相同的值,最后为 1。我描述的情况是否真的发生了?
我觉得你对MPI_Bcast这个功能理解的不太好。 MPI_Bcast实际上是一种MPI集体通信方式,属于某个通信者的每个进程都需要参与进来。所以对于MPI_Bcast这个函数,不仅是发送广播数据的进程,接收广播数据的进程也需要同步调用该函数,才能达到所有参与的数据广播的目的过程。
在你给出的程序中,尤其是这部分:
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);
}
我认为你的意思是让排名为 0 的进程(进程 0)将它的 x 值广播给其他进程,但在你的代码中,当你使用 if 时,只有进程 0 调用 MPI_Bcast 函数-else 段。那么其他进程是做什么的呢?对于等级为 1 的进程(进程 1),它不会调用进程 0 调用的相同 MPI_Bcast 函数,尽管它确实调用了另一个 MPI_Bcast 函数来广播其 x 值( root 在这两个 MPI_Bcast 函数之间是不同的。因此,如果只有进程 0 调用 MPI_Bcast 函数,它实际上只是将 x 的值广播给它自己,而存储在其他进程中的 x 的值不会'一点都不受影响。这也是进程 1 的相同条件。因此在您的程序中,每个进程的 x 打印值应与最初分配时相同,并且不会出现您所关心的数据不确定性问题。
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);
请注意您的用法的不同之处。 same MPI_Bcast
要求 all 排名。 root 将发送,其他人将执行 recv。
如果不同的进程向某个通信者所在组中的其他进程广播不同的值,会发生什么?
以下程序运行以两个进程为例,
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 运行s 比进程 1 快,它会比进程 1 更早广播它的值,因此进程 1 在开始广播其值时将与进程 0 具有相同的值,因此打印出 x 的值两者都是 0。但是,如果进程 0 运行 比进程 1 慢,则进程 0 将具有与进程 1 相同的值,最后为 1。我描述的情况是否真的发生了?
我觉得你对MPI_Bcast这个功能理解的不太好。 MPI_Bcast实际上是一种MPI集体通信方式,属于某个通信者的每个进程都需要参与进来。所以对于MPI_Bcast这个函数,不仅是发送广播数据的进程,接收广播数据的进程也需要同步调用该函数,才能达到所有参与的数据广播的目的过程。
在你给出的程序中,尤其是这部分:
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);
}
我认为你的意思是让排名为 0 的进程(进程 0)将它的 x 值广播给其他进程,但在你的代码中,当你使用 if 时,只有进程 0 调用 MPI_Bcast 函数-else 段。那么其他进程是做什么的呢?对于等级为 1 的进程(进程 1),它不会调用进程 0 调用的相同 MPI_Bcast 函数,尽管它确实调用了另一个 MPI_Bcast 函数来广播其 x 值( root 在这两个 MPI_Bcast 函数之间是不同的。因此,如果只有进程 0 调用 MPI_Bcast 函数,它实际上只是将 x 的值广播给它自己,而存储在其他进程中的 x 的值不会'一点都不受影响。这也是进程 1 的相同条件。因此在您的程序中,每个进程的 x 打印值应与最初分配时相同,并且不会出现您所关心的数据不确定性问题。
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);
请注意您的用法的不同之处。 same MPI_Bcast
要求 all 排名。 root 将发送,其他人将执行 recv。