【发布时间】:2013-05-21 02:47:33
【问题描述】:
我几天以来一直在尝试解决这个问题。我有一个混合 OpenMPI + Pthreads 程序。这意味着,程序在多台机器上运行,每台机器运行一组 pthread。
为了简化问题,我们假设有 3 台机器,每台运行 2 个 pthread:P1 和 P2。现在,每台机器上的 P1 使用 MPI_Send/Recv 不断地与其他机器上的 P1 通信。同时,P2 做一些工作并定期调用 MPI_Barrier(与其他机器上的 P2 同步)。这会导致 MPI_Send/Recv 方法失败,并且程序会因随机错误而崩溃,例如:对等方重置连接 / 错误文件描述符 / tcp 错误 / 等。
- 如果我从 P2 中注释掉 MPI_Barrier,一切正常。
- 如果我从 P1 中注释掉 MPI_Send/Recv,一切正常。
- 如果 P2 中的 MPI_Barrier 和 P1 中的 MPI_Send/Recv 均未注释,则程序会崩溃。
因此,我能想到的唯一原因是 MPI_Barrier 和 MPI_Send/Recv 在底层通信级别相互影响。
但是,我确实需要 P1 中的通信(如 MPI_Send/Recv)和 P2 中的同步(如 MPI_Barrier)以保持语义正确性。而且我同时需要它们(这意味着我不想在达到同步点之前暂停通信,然后从它离开的地方继续通信)。
有没有办法做到这一点?
【问题讨论】:
-
您是否对 P1 和 P2 集使用单独的 MPI 通信器?同一台机器上的 P1 和 P2 是否以某种方式相互同步?如果您提供您的通信代码会更好(仅简化为通信/同步操作)。
-
另外,请确保使用
MPI_Init_thread和MPI_THREAD_MULTIPLE初始化MPI(绝不使用MPI_Init)。 -
[1] 我对 P1 和 P2 集使用相同的默认 (MPI_COMM_WORLD) 通信器。 [2] 是的,同一台机器上的 P1 和 P2 使用 pthread 同步进行同步。基本上在初始化期间,P2 向 P1 发出信号以开始通信,在关机期间,P2 向 P1 发出信号以停止通信。在某种程度上,您可以将 P2 视为控制 P1 启动和关闭的主机。 [3] 我最初计划从现有代码中提供最少的通信代码。但由于代码分布在不同的文件/方法中,这样做有点困难。
-
我用 MPI_Init 初始化 MPI。之后,在每台机器上,我使用 pthread_create() 创建 pthread。我不知道 MPI_Init_thread;我会调查的。
-
嗯,这解释了很多。 MPI 实现未在线程安全模式下运行,因此来自多个线程的并发调用会导致各种错误。