对于我开发的软件包,我使用主/工作方案,其中一个进程将工作分配给其他进程。分发的工作是独立的,但需要大量可变的时间才能完成,并且从共享内存环境中获益匪浅。所以,现在我有一个进程/节点,因此每个MPI进程具有例如12个处理器和用于运行OpenMP的共享存储器环境。这一切都很棒,但后来我的“主”进程有11个空闲处理器,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创建主/工混合。您可以:
MPI_Test
的MPI实现,这通常会带来其他性能问题。MPI_Iprobe
来确定结果消息是否已到达。如果是,则运行主循环的一次迭代,发布新的非阻塞接收并继续进行工作程序迭代。或者使用{f:if(condition: settings.media.responsive{f:count(subject: records)}, then: 'true', else: 'false')}
代替非阻止接收。两者都会显着增加代码的复杂性,第二个会完全搞乱主/代码分离。我宁愿坚持上面明显的解决方案。