主工模型和混合MPI / OpenMP

时间:2017-05-10 13:32:05

标签: mpi openmp

对于我开发的软件包,我使用主/工作方案,其中一个进程将工作分配给其他进程。分发的工作是独立的,但需要大量可变的时间才能完成,并且从共享内存环境中获益匪浅。所以,现在我有一个进程/节点,因此每个MPI进程具有例如12个处理器和用于运行OpenMP的共享存储器环境。这一切都很棒,但后来我的“主”进程有11个空闲处理器,1个只是分发工作=(我有一些想法来解决这个问题,我正在寻找任何输入或其他想法:

  • 在主节点上,分配一个处理器来分配工作,以及 其他11个实际上做的工作。从概念上讲,这似乎是一个 明显的解决方案,但我还没弄清楚如何实际 实施这样的计划。
  • 让主节点通过非阻塞发送分发所有工作 程序一开始,就参与完成工作。同样,这在概念上很简单,但不知道MPI是否真的支持这样的方案(我认为它没有)。这可以说,发送了100条消息,等待任何一个进程接收。
  • 让所有流程加载所有已分配工作的数据,并从不同点开始。当进程开始执行任务时,向所有其他进程广播此任务正在进行中,因此其他进程不会选择该任务。这似乎是最好的选择,但我担心在广播到达之前同时选择任务的两个过程。虽然两个进程不太可能在同一时间选择一个新任务,但这似乎是可能的。

1 个答案:

答案 0 :(得分:1)

显而易见的解决方案非常简单易用。首先,创建一个类似于此的MPI主机文件(Open MPI格式):

node1 slots=2
node2 slots=1
node3 slots=1
node4 slots=1

然后运行:

mpiexec --hostfile hostfile.txt -n 2 -x OMP_NUM_THREADS=11 a.out : \
                                -n 3 -x OMP_NUM_THREADS=12 a.out

将会发生两个a.out副本node1将在OMP_NUM_THREADS上启动并将成为0和1等级。对于那些环境变量OMP_NUM_THREADS将设置为11。排名0是主进程,并且它不执行OpenMP并行区域,omp_set_num_threads(1)的值与它无关。否则,您可以通过显式调用OMP_NUM_THREADS轻松阻止任何OpenMP代码使用多个线程。等级1将是其中一个工作者,它将在并行区域中使用11个线程。在其余节点上,只会启动一个MPI进程,MPI_THREAD_MULTIPLE的值将设置为12,因此OpenMP运行时将使用所有CPU。这些流程将成为2,3级和4级。工人1会慢一点,但你已经说过你的工作项目需要不同的时间才能完成,所以我猜有一些内置的工作平衡器。

您还可以为等级0创建主/工混合。您可以:

  • 在单独的线程中运行master和worker代码。这将使主代码复杂化,因为该特定工作人员将不得不通过不同的机制获得工作,例如,通过共享内存队列或其他东西,比其他工人。也可以让主机向自己发送消息,但是它需要能够MPI_Test的MPI实现,这通常会带来其他性能问题。
  • 使用worker 1保存主代码,尤其是当worker代码执行某种循环时。在该特定情况下,您可以发布工作结果的非阻塞接收,然后在工作循环的每次迭代中使用MPI_Iprobe来确定结果消息是否已到达。如果是,则运行主循环的一次迭代,发布新的非阻塞接收并继续进行工作程序迭代。或者使用{f:if(condition: settings.media.responsive{f:count(subject: records)}, then: 'true', else: 'false')} 代替非阻止接收。

两者都会显着增加代码的复杂性,第二个会完全搞乱主/代码分离。我宁愿坚持上面明显的解决方案。