为什么 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_attachMPI_Bsend。可能还有一种方法可以更改系统缓冲区大小(例如 IBM 系统上的 MP_BUFFER_MEM 系统变量)。

不过这种消息不被回复的情况在实际中应该不会出现。在上面的示例中,可以交换 ki 循环的顺序以防止消息堆积。