【问题标题】:Deadlock in Microsft MPI MPI_IsendMicrosft MPI MPI_Isend 中的死锁
【发布时间】:2016-01-26 16:34:02
【问题描述】:

我有以下带有 Microsoft MPI 的 c/c++ 代码

#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
int main (int argc, char *argv[])
 {
  int  err, numtasks, taskid;
  int out=0,val;
  MPI_Status status;
  MPI_Request req;

  err=MPI_Init(&argc, &argv);
  err=MPI_Comm_size(MPI_COMM_WORLD, &numtasks);
  err=MPI_Comm_rank(MPI_COMM_WORLD, &taskid);


  int receiver=(taskid+1)% numtasks;
  int sender= (taskid-1+numtasks)% numtasks;
  printf("sender %d, receiver %d, rank %d\n",sender,receiver, taskid);

  val=50;   
  MPI_Isend(&val, 1, MPI_INT, receiver, 1, MPI_COMM_WORLD, &req);
  MPI_Irecv(&out, 1, MPI_INT, sender, 1, MPI_COMM_WORLD, &req);
  printf ("Rank: %d , Value: %d\n", taskid, out );
  err=MPI_Finalize();
  return 0;
 }

如果使用超过 2 个进程启动应用程序,则会陷入死锁。 使用 2 个进程,应用程序可以工作,但不会执行“输出”写入。 此代码适用于 linux mpi 发行版,问题似乎仅在 microsoft 版本中。有什么帮助吗?

【问题讨论】:

    标签: c++ mpi ms-mpi


    【解决方案1】:

    首先,每个 MPI 进程执行两次通信:一次发送和一次接收。因此,您需要存储两个请求 (MPI_Request req[2]) 和两个状态检查 (MPI_Status status[2])。

    其次,您需要在调用非阻塞发送/接收后等待,以确保它们正确完成。

    MPI_Isend(&val, 1, MPI_INT, receiver, 1, MPI_COMM_WORLD, &req[0]);
    MPI_Irecv(&out, 1, MPI_INT, sender, 1, MPI_COMM_WORLD, &req[1]);
    
    // While the communication is happening, here you can overlap computation
    // on data that is NOT being currently communicated, with the communication of val/out
    
    MPI_Waitall(2, req, status);
    
    // Now both the send and receive have been finished for this process, 
    // and we can access out, assured that it is valid
    
    printf ("Rank: %d , Value: %d\n", taskid, out);
    

    至于为什么这适用于 Linux 发行版,而不是 Microsoft 发行版...我只能假设 Linux 实现在底层有效地将非阻塞通信实现为阻塞通信。也就是说,他们在“作弊”并在应该完成之前为您完成了您的沟通。这使他们更容易,因为他们不必跟踪有关通信的尽可能多的信息,但它也破坏了您重叠计算和通信的能力。你不应该依赖它来工作。

    【讨论】:

    • 为什么我需要等待非阻塞调用?我应该有不一致的数据而不是死锁,对吧?为什么在 linux 发行版中我不需要“等待”调用?
    • @Discipulos 你是对的。非阻塞通信允许您在进程之间拥有不一致的数据。但是,在您可以访问数据之前,您必须确认通信完成。因此需要等待。我已经编辑了这篇文章,以便更清楚地展示这可以让你做什么。
    • 可能微软实现了非纯非阻塞通信,这解释了我注意到的行为。谢谢!
    猜你喜欢
    • 2013-12-25
    • 1970-01-01
    • 1970-01-01
    • 2011-08-01
    • 2019-05-29
    • 2023-04-11
    • 2017-03-04
    • 2016-10-03
    • 2014-04-04
    相关资源
    最近更新 更多