2015-11-13 44 views
0

我正在努力寻找使用MPICH(hydra)执行混合OpenMP/MPI作业的正确方法。在MPICH中执行混合OpenMP/MPI作业

我很容易启动这些进程并且他们确实创建线程,但他们被困在与他们的主线程相同的核心上,无论我尝试什么类型的-bind-to

如果我明确设置GOMP_CPU_AFFINITY0-15我得到所有线程传播,但只提供如果我有每个节点1进程。我不希望这样,我想每个套接字一个进程。

设置OMP_PROC_BIND=false没有明显的效果。

我试图

export OMP_NUM_THREADS=8 
export OMP_PROC_BIND="false" 
mpiexec.hydra -n 2 -ppn 2 -envall -bind-to numa ./a.out 

我得到的是所有的流程坐在核0-7 100%和核心8-15几个线程,但其中只有一个接近100%的一个许多不同的组合的例子(他们正在等待第一个进程)。

#!/bin/sh 

GOMP_CPU_AFFINITY=$(grep ^Cpus_allowed_list /proc/self/status | grep -Eo '[0-9,-]+') 
export GOMP_CPU_AFFINITY 
exec $* 

回答

2

由于libgomp缺少英特尔KMP_AFFINITYrespect条款相当于,你可以通过提供一个包装脚本读取允许的CPU从/proc/PID/status(Linux特有)名单破解它周围这应该与-bind-to numa然后。

+0

我想你想'grep^Cpus_allowed_list/proc/self/status | grep -Eo'[0-9, - ] +'',工作! –

+0

实际上我错过了一个'猫',但你的更好。 –

3

当运行混合MPI/OpenMP代码时,每当MPI库和OpenMP运行时默认情况下协调不好时,我的OpenMP线程与套接字/ NUMA节点绑定的方式有所不同。这个想法是使用numactl及其绑定属性。这甚至还有额外的优点,不仅将线程绑定到套接字,还包括内存,从而强化良好的内存局部性并最大化带宽。为此,我首先禁用任何MPI和/或OpenMP绑定(前者对应mpiexec选项,后者将OMP_PROC_BIND设置为false)。然后我用下面的omp_bind.sh shell脚本:

#!/bin/bash 

numactl --cpunodebind=$(($PMI_ID % 2)) --membind=$(($PMI_ID % 2)) "[email protected]" 

我跑我的代码是这样的:

OMP_PROC_BIND="false" OMP_NUM_THREADS=8 mpiexec -ppn 2 -bind-to-none omp_bind.sh a.out args 

根据机器上的插座的数量,2将需要在调整贝壳。同样,PMI_ID取决于所使用的版本mpiexec。我有时看到MPI_RANK,PMI_RANK

但无论如何,我总是找到一种方法让它工作,并且有时候内存绑定非常方便,特别是为了避免IO缓冲区消耗所有内存的潜在缺陷第一个NUMA节点,导致在第一个套接字上运行的进程的代码内存,在第二个NUMA节点上分配内存。

+0

有趣。你是否使用'numactl --membind',因为MPICH和兄弟姐妹不能单独进行内存绑定?Open MPI执行内存绑定,甚至在共享内存传输中实现一些NUMA优化。只是出于好奇 - 我是一个开放的MPI(在很小程度上是一个英特尔MPI)用户,MPICH和co对我来说是相当陌生的。 –

+0

@HristoIliev TBH,我在很久以前就说过要这样做,因为我有时会在没有正确配置MPI的机器上运行性能测试。使用'numactl'这种方式要简单得多,而不是试图修复MPI配置。而此时OpenMP没有任何本地绑定。如今,我主要是英特尔MPI用户,但我不太确定如何管理内存绑定。可以肯定的是,这个旧的同样的'numactl'技巧在需要的时候仍然可以工作,而且,由于自己设置错误,它允许评估潜在的NUMA效果,代码 – Gilles

+0

感谢您的其他选择。我会调查两者。我有一些性能问题,看到效果会很有趣。 –