【问题标题】:Why does MPI_Recv fail when there is an accumulation of MPI_Send calls为什么 MPI_Send 调用累积时 MPI_Recv 失败
【发布时间】:2016-11-24 21:42:39
【问题描述】:

我有一个 MPI 程序,其中工人等级(等级!= 0)发出一堆 MPI_Send 调用,而主人等级(等级 == 0)接收所有这些消息。但是,我在 MPI_Recv 中遇到了致命错误 - MPI_Recv(...) failed, Out of memory。

这是我在 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 字节用于双倍 * 1000000 次迭代),所以我不认为“内存不足”指的是 RAM 等任何物理内存。

感谢任何见解,谢谢!

【问题讨论】:

  • 对于这个特定的问题,了解您正在使用哪种 MPI 实现以及采用何种配置非常重要。
  • 在 Windows 7 上使用 MS-MPI v 7.1

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


【解决方案1】:

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

但是,这种单发消息的情况在实践中可能不应该发生。在上面的示例中,ki 循环的顺序可以互换,以防止这种消息堆积。

【讨论】:

  • 感谢有关系统缓冲区的信息。我尝试切换 k 和 i 循环的顺序,但程序的行为保持不变。
  • 从这里technet.microsoft.com/en-us/library/… 看起来 MS-MPI 不提供对设置系统缓冲区大小的任何控制。
猜你喜欢
  • 2015-01-26
  • 2011-11-11
  • 2017-10-25
  • 2016-04-22
  • 2011-11-05
  • 2014-04-17
  • 2011-01-24
  • 1970-01-01
  • 2016-09-09
相关资源
最近更新 更多