当所有级别都可以看到将要广播的数据时,使用 MPI_Bcast 有什么意义?

What's the point of using MPI_Bcast when all ranks can see the data which will be broadcasted?

我只是在考虑使用MPI_Bcast背后的原因,因为当我不向所有级别广播整数N时,他们可以看到N。看看代码及其结果。在广播之前和之后,整数 N 对所有级别都可见。那么,这里有什么意义呢? 此外,使用 MPI_Bcast 更改调用每个等级的顺序是否有意义?

#include <iostream>
#include "mpi.h"
using namespace std; 
int main()
{
   MPI_Init(NULL, NULL);
    int rank, size; 
    int N=9 ;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    cout << " Hello from rank : " << rank << " N is: " << N << endl;
    MPI_Bcast(&N, 1, MPI_INT, 0, MPI_COMM_WORLD);
    cout << " Hello from rank : " << rank << " N is: " <<N<<endl;
    MPI_Finalize();

}

结果:

 Hello from rank : 1 N is: 9
 Hello from rank : 3 N is: 9
 Hello from rank : 0 N is: 9
 Hello from rank : 2 N is: 9
 Hello from rank : 0 N is: 9
 Hello from rank : 1 N is: 9
 Hello from rank : 2 N is: 9
 Hello from rank : 3 N is: 9

在您的示例中,该值是硬编码的。广播一个已知的值是没有意义的。

如果它是在启动后计算的,比如说,排名 0 怎么办?然后 MPI_Bcast 可用于将其广播到所有其他级别。

    MPI_Init(NULL, NULL);
    int rank, size; 
    int N = 0;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    cout << " Hello from rank : " << rank << " N is: " << N << endl;
    if (rank == 0) {
        N = 9;
    }
    MPI_Bcast(&N, 1, MPI_INT, 0, MPI_COMM_WORLD);
    cout << " Hello from rank : " << rank << " N is: " <<N<<endl;
    MPI_Finalize();

打印:

 Hello from rank : 0 N is: 0
 Hello from rank : 3 N is: 0
 Hello from rank : 2 N is: 0
 Hello from rank : 1 N is: 0
 Hello from rank : 0 N is: 9
 Hello from rank : 1 N is: 9
 Hello from rank : 2 N is: 9
 Hello from rank : 3 N is: 9

MPI_Bcast 在示例中的 N 实际上会被广播排名更改的情况下很有用。考虑一下:

#include <iostream>
#include "mpi.h"

using namespace std;

int main()
{
    MPI_Init(NULL, NULL);
    int rank, size;
    int N=9 ;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    cout << " Hello from rank : " << rank << " N is: " << N << endl;

    // Change N on the rank that will broadcast
    if (rank == 0) {
        N = 18;
    }

    MPI_Bcast(&N, 1, MPI_INT, 0, MPI_COMM_WORLD);
    cout << " Hello from rank : " << rank << " N is: " <<N<<endl;
    MPI_Finalize();
}

等级 0 已更改 N 并希望将其自己的值发送给所有其他等级。它可以使用 MPI_Send and MPI_Recv or it can use some form of collective communication, like MPI_Bcast.

将其单独发送到每个级别

MPI_Bcast 是正确的选择,因为它针对它提供的功能进行了优化:从一个到所有发送信息。建议你看看它的通信算法就明白了。

由于通信是CPU并行化的瓶颈,因此要谨慎选择通信算法。经验法则是,无论是为集体通信而设计的,都应该用于此类,而不是点对点的发送-接收方法(即 rank 0 单独发送给其他 rank)。

one-to-all broadcast在实践中其实是很常见的情况,至少在科学计算中是这样,比如一个rank需要读取输入参数,为模拟做准备,然后广播一些必要的信息到所有其他级别。在计算过程中可能还需要广播,其中一个等级需要与其他等级的子集或所有等级共享其结果。