【问题标题】:Unexpected behavior with MPI_Ssend and MPI_RecvMPI_Ssend 和 MPI_Recv 的意外行为
【发布时间】:2013-07-11 14:05:05
【问题描述】:

在这个小代码示例中,我在 MPI(使用 C++)中发现了一些意外行为:

int rank, size;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);

if(rank == 1) {
    int *sendDone = (int*)malloc(sizeof(int));    
    *sendDone = 1;
    MPI_Ssend(sendDone,1,MPI_INT, 0, 1,MPI_COMM_WORLD);  
    foo();    
} else {
    int *rcvDone = (int*)malloc(sizeof(int));
    bar();
    while(*rcvDone != 1) {
        MPI_Recv(rcvDone,1,MPI_INT, MPI_ANY_SOURCE, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    }
    cout << *rcvDone << endl;
}
MPI_Finalize();

使用以下命令编译和运行:

mpic++ sim.cc -o sim
mpirun -n 2 ./sim

代码应按以下顺序执行:

bar();
foo();

因为在 bar() 执行之后进程#0 开始接收。但实际上,foo() 有时会在 bar() 完成之前开始。有人可以向我解释一下并给出解决方案吗?

【问题讨论】:

  • bar()foo() 在做什么来表明他们已被调用?他们写信给stderr吗?
  • 测试前请务必初始化rcvDone

标签: c++ mpi


【解决方案1】:
  1. 您还没有说如何检查首先调用哪个函数。在屏幕上计算某些内容并不能保证显示消息的正确顺序(至少在使用 MPI 时)。

  2. 您不需要将 MPI_Recv 放入循环中,因为它是一个阻塞函数。当您没有为 *rcvDone 分配起始值时,甚至不推荐它。

  3. 将 malloc 与某些 MPI 函数一起使用是不安全的。阅读http://www.mcs.anl.gov/research/projects/mpi/www/www3/MPI_Ssend.html上的“线程和中断安全”部分

【讨论】:

猜你喜欢
  • 2017-10-25
  • 2013-07-09
  • 1970-01-01
  • 2017-03-27
  • 2011-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多