我有一个代码可以计算某些导体的热传递。在一个导体中发生的事情不会影响模型中的其他导体。所以我试图让这些导体的解决方案并行运行,每个处理器采用不同的导体组。现在,我认为代码可以在一个核心上运行,直到它到达我放置命令的循环:
MPI_INIT
然后在我请求的多个核心上运行此部分代码,然后在命令之后返回运行在一个核心上:
MPI_FINALIZE
遇到了。但我所看到的是输入文件由两个内核读入(如果我使用2个内核),并且所有输出也被打印两次。 MPI不能像我想的那样工作吗?如果没有,那么我怎样才能实现我想要的行为呢?我只希望代码的一个段在多个内核上运行代码,而不是在MPI_INIT和MPI_FINALIZE之外的任何其他子例程或代码部分中运行。
答案 0 :(得分:8)
这是一种常见的误解,尤其是那些对OpenMP有经验的人,其中线程在程序的各个点分叉和连接。
在MPI中,MPI_Init
和MPI_Finalize
初始化并完成您的MPI库;而已。虽然标准是有目的地保证在Init之前和Finalize之后发生的事情,但实际上你的mpirun
或mpiexec
命令通常会创建和启动进程。如果您输入
mpirun -np 4 hostname
例如,启动了四个进程,每个进程运行hostname
命令 - 这绝对不是MPI可执行文件,并且没有任何MPI_Init
或MPI_Finalize
打电话给它。每个进程都运行可执行文件,从头到尾,因此您将获得四个输出。它是启动进程的mpirun(或mpiexec),而不是程序内的任何MPI函数调用。
然后,在您的程序中,整个程序将由您请求的多个进程运行。
答案 1 :(得分:3)
我认为我不完全理解这个问题,但首先要注意的是MPI最多可以初始化一次。如此反复做
MPI_Init
...
MPI_Finalize
是不允许的。此外,MPI_Init
和MPI_Finalize
是昂贵的操作;你不想在循环中调用它们。
MPI最初是围绕静态流程模型设计的,这意味着一组流程启动,工作和退出。听起来您希望在运行时更改进程数。这在MPI-2中是可能的(见MPI_Comm_spawn
)。
另一方面,持续启动和关闭进程将会很慢。仅仅因为一个进程调用MPI_Init
并不意味着它必须参与所有通信。以下是我将如何处理这个问题:
MPI_Init
,即使那些只能在本地运行的进程。MPI_Comm_create
进行通信的流程创建新的通信器,并将其用于所有通信,而不是MPI_COMM_WORLD
。MPI_Finalize
。