为什么 MPI_Recv 调用累积 MPI_Send 会失败
Why does MPI_Recv fail when there is an accumulation of MPI_Send calls
我有一个 MPI 程序,其中 worker ranks (rank != 0) 发出一堆 MPI_Send 调用,master rank (rank == 0) 接收所有这些消息。但是,我 运行 在 MPI_Recv 中出现致命错误 - MPI_Recv(...) 失败,内存不足。
这是我在 Visual Studio 2010 年编译的代码。
我 运行 可执行文件是这样的:
mpiexec -n 3 MPIHelloWorld.exe
int main(int argc, char* argv[]){
int numprocs, rank, namelen, num_threads, thread_id;
char processor_name[MPI_MAX_PROCESSOR_NAME];
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Get_processor_name(processor_name, &namelen);
if(rank == 0){
for(int k=1; k<numprocs; k++){
for(int i=0; i<1000000; i++){
double x;
MPI_Recv(&x, 1, MPI_DOUBLE, k, i, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
}
}
}
else{
for(int i=0; i<1000000; i++){
double x = 5;
MPI_Send(&x, 1, MPI_DOUBLE, 0, i, MPI_COMM_WORLD);
}
}
}
如果我 运行 只有 2 个进程,程序不会崩溃。所以看起来问题是当来自第三等级(也称为第二个工作节点)的 MPI_Send 调用累积时。
如果我将迭代次数减少到 100,000 次,那么我可以 运行 使用 3 个进程而不会崩溃。但是,一百万次迭代发送的数据量约为 8 MB(8 字节用于 double * 1000000 次迭代),所以我不认为 "Out of Memory" 指的是任何物理内存,如 RAM。
感谢任何见解,谢谢!
MPI_send
操作将数据存储在 system buffer ready to send. The size of this buffer and where it is stored is implementation specific 上(我记得听说这甚至可以在互连中)。在我的例子中(linux with mpich)我没有收到内存错误。显式更改此缓冲区的一种方法是使用 MPI_buffer_attach
和 MPI_Bsend
。可能还有一种方法可以更改系统缓冲区大小(例如 IBM 系统上的 MP_BUFFER_MEM
系统变量)。
不过这种消息不被回复的情况在实际中应该不会出现。在上面的示例中,可以交换 k
和 i
循环的顺序以防止消息堆积。
我有一个 MPI 程序,其中 worker ranks (rank != 0) 发出一堆 MPI_Send 调用,master rank (rank == 0) 接收所有这些消息。但是,我 运行 在 MPI_Recv 中出现致命错误 - MPI_Recv(...) 失败,内存不足。
这是我在 Visual Studio 2010 年编译的代码。 我 运行 可执行文件是这样的:
mpiexec -n 3 MPIHelloWorld.exe
int main(int argc, char* argv[]){
int numprocs, rank, namelen, num_threads, thread_id;
char processor_name[MPI_MAX_PROCESSOR_NAME];
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Get_processor_name(processor_name, &namelen);
if(rank == 0){
for(int k=1; k<numprocs; k++){
for(int i=0; i<1000000; i++){
double x;
MPI_Recv(&x, 1, MPI_DOUBLE, k, i, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
}
}
}
else{
for(int i=0; i<1000000; i++){
double x = 5;
MPI_Send(&x, 1, MPI_DOUBLE, 0, i, MPI_COMM_WORLD);
}
}
}
如果我 运行 只有 2 个进程,程序不会崩溃。所以看起来问题是当来自第三等级(也称为第二个工作节点)的 MPI_Send 调用累积时。
如果我将迭代次数减少到 100,000 次,那么我可以 运行 使用 3 个进程而不会崩溃。但是,一百万次迭代发送的数据量约为 8 MB(8 字节用于 double * 1000000 次迭代),所以我不认为 "Out of Memory" 指的是任何物理内存,如 RAM。
感谢任何见解,谢谢!
MPI_send
操作将数据存储在 system buffer ready to send. The size of this buffer and where it is stored is implementation specific 上(我记得听说这甚至可以在互连中)。在我的例子中(linux with mpich)我没有收到内存错误。显式更改此缓冲区的一种方法是使用 MPI_buffer_attach
和 MPI_Bsend
。可能还有一种方法可以更改系统缓冲区大小(例如 IBM 系统上的 MP_BUFFER_MEM
系统变量)。
不过这种消息不被回复的情况在实际中应该不会出现。在上面的示例中,可以交换 k
和 i
循环的顺序以防止消息堆积。