为什么MPI_Recv在MPI_Send调用累积时失败

时间:2016-11-24 21:42:40

标签: c++ out-of-memory mpi

我有一个MPI程序,其中worker rank(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(双倍* 1000000次迭代时为8个字节),因此我认为“内存不足”指的是任何物理内存,如RAM。

感谢任何见解,谢谢!

1 个答案:

答案 0 :(得分:1)

MPI_send操作将数据存储在准备发送的system buffer上。此缓冲区的大小及其存储位置为implementation specific(我记得听说这甚至可以在互连中)。在我的情况下(linux与mpich)我没有得到内存错误。明确更改此缓冲区的一种方法是将MPI_buffer_attachMPI_Bsend一起使用。可能还有一种方法可以更改系统缓冲区大小(例如IBM系统上的MP_BUFFER_MEM系统变量)。

然而,在实践中可能不会发生这种无回复消息的情况。在上面的示例中,可以交换ki循环的顺序,以防止此消息的累积。