当所有级别都可以看到将要广播的数据时,使用 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需要读取输入参数,为模拟做准备,然后广播一些必要的信息到所有其他级别。在计算过程中可能还需要广播,其中一个等级需要与其他等级的子集或所有等级共享其结果。
我只是在考虑使用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需要读取输入参数,为模拟做准备,然后广播一些必要的信息到所有其他级别。在计算过程中可能还需要广播,其中一个等级需要与其他等级的子集或所有等级共享其结果。