使用MPI在顺序和并行之间切换

时间:2012-06-19 19:34:36

标签: mpi

我有一个代码可以计算某些导体的热传递。在一个导体中发生的事情不会影响模型中的其他导体。所以我试图让这些导体的解决方案并行运行,每个处理器采用不同的导体组。现在,我认为代码可以在一个核心上运行,直到它到达我放置命令的循环:

MPI_INIT

然后在我请求的多个核心上运行此部分代码,然后在命令之后返回运行在一个核心上:

MPI_FINALIZE
遇到了

。但我所看到的是输入文件由两个内核读入(如果我使用2个内核),并且所有输出也被打印两次。 MPI不能像我想的那样工作吗?如果没有,那么我怎样才能实现我想要的行为呢?我只希望代码的一个段在多个内核上运行代码,而不是在MPI_INIT和MPI_FINALIZE之外的任何其他子例程或代码部分中运行。

2 个答案:

答案 0 :(得分:8)

这是一种常见的误解,尤其是那些对OpenMP有经验的人,其中线程在程序的各个点分叉和连接。

在MPI中,MPI_InitMPI_Finalize初始化并完成您的MPI库;而已。虽然标准是有目的地保证在Init之前和Finalize之后发生的事情,但实际上你的mpirunmpiexec命令通常会创建和启动进程。如果您输入

mpirun -np 4 hostname
例如,启动了四个进程,每个进程运行hostname命令 - 这绝对不是MPI可执行文件,并且没有任何MPI_InitMPI_Finalize打电话给它。每个进程都运行可执行文件,从头到尾,因此您将获得四个输出。它是启动进程的mpirun(或mpiexec),而不是程序内的任何MPI函数调用。

然后,在您的程序中,整个程序将由您请求的多个进程运行。

答案 1 :(得分:3)

我认为我不完全理解这个问题,但首先要注意的是MPI最多可以初始化一次。如此反复做

MPI_Init
...
MPI_Finalize

是不允许的。此外,MPI_InitMPI_Finalize是昂贵的操作;你不想在循环中调用它们。

MPI最初是围绕静态流程模型设计的,这意味着一组流程启动,工作和退出。听起来您希望在运行时更改进程数。这在MPI-2中是可能的(见MPI_Comm_spawn)。

另一方面,持续启动和关闭进程将会很慢。仅仅因为一个进程调用MPI_Init并不意味着它必须参与所有通信。以下是我将如何处理这个问题:

  1. 启动一个流程池。在程序开头就所有进程调用MPI_Init,即使那些只能在本地运行的进程。
  2. 在每次循环迭代中,为需要使用MPI_Comm_create进行通信的流程创建新的通信器,并将其用于所有通信,而不是MPI_COMM_WORLD
  3. 在程序结束时,所有进程都会调用MPI_Finalize