使用MPI_Send和MPI_Recv发送大型std::vector不';不完整
我正在尝试使用MPI发送std::vector。当向量很小时,这可以很好地工作,但当向量很大时(向量中超过~15k倍)就不起作用。当试图发送一个20k双倍的向量时,程序只是在CPU为100%的情况下运行 这里有一个最小的例子使用MPI_Send和MPI_Recv发送大型std::vector不';不完整,mpi,stdvector,Mpi,Stdvector,我正在尝试使用MPI发送std::vector。当向量很小时,这可以很好地工作,但当向量很大时(向量中超过~15k倍)就不起作用。当试图发送一个20k双倍的向量时,程序只是在CPU为100%的情况下运行 这里有一个最小的例子 #include <vector> #include <mpi.h> using namespace std; vector<double> send_and_receive(vector<double> &loc
#include <vector>
#include <mpi.h>
using namespace std;
vector<double> send_and_receive(vector<double> &local_data, int n, int numprocs, int my_rank) {
MPI_Send(&local_data[0], n, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD);
if (my_rank == 0) {
vector<double> global_data(numprocs*n);
vector<double> temp(n);
for (int rank = 0; rank < numprocs; rank++) {
MPI_Recv(&temp[0], n, MPI_DOUBLE, rank, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
for (int i = 0; i < n; i++) {
global_data[rank*n + i] = temp[i];
}
}
return global_data;
}
return vector<double>();
}
int main(int args, char *argv[]) {
int my_rank, numprocs;
// MPI initialization
MPI_Init (&args, &argv);
MPI_Comm_rank (MPI_COMM_WORLD, &my_rank);
MPI_Comm_size (MPI_COMM_WORLD, &numprocs);
int n = 15000;
vector<double> local_data(n);
for (int i = 0; i < n; i++) {
local_data[i] = n*my_rank + i;
}
vector<double> global_data = send_and_receive(local_data, n, numprocs, my_rank);
MPI_Finalize();
return 0;
}
并使用
mpirun -n 2 a.out
当我用n=15000
运行时,程序成功完成,但用n=17000
或n=20000
运行时,它永远不会完成,两个CPU的运行率为100%,直到我强制关闭程序
有人知道问题出在哪里吗?
MPI\u Send
是一个有趣的电话。如果有足够的内部缓冲区来存储输入,它可能会返回—它所做的唯一保证是MPI不再需要输入缓冲区。但是,如果没有足够的内部缓冲区空间,调用将阻塞,直到相反的MPI_Recv
调用开始接收数据。看看这是怎么回事?由于缓冲区空间不足,这两个进程都会发送该块。当调试类似的问题时,将MPI\u Send
替换为MPI\u Send
您可能的解决方案是:
- 使用缓冲发送,
MPI\u Bsend
- 使用
MPI\u Sendrecv
- 备用发送/接收对,以便每个发送都有一个匹配的接收(例如,奇数proc发送,偶数recv,反之亦然)
- 使用非阻塞发送,
MPI\u Isend
请参见非常感谢,我刚才正在查看Isend/Irecv。如果我只是在示例中使用Isend和Irecv,我是否应该在接收之前添加
MPI\u屏障(MPI\u COMM\u WORLD)
?不需要Irecv,您只需要发送返回即可。也不需要障碍物。
mpirun -n 2 a.out