在LSF混合MPI / OpenMP的(Hybrid MPI/OpenMP in LSF)

2019-07-20 20:20发布

我通过移动并行的OpenMP到集群的程序。 群集正在使用熔岩1.0作为调度器,并具有在每个节点8个核心。 我用了一个MPI包装作业脚本做多主机并行。

下面是作业脚本:

#BSUB -q queue_name
#BSUB -x

#BSUB -R "span[ptile=1]"
#BSUB -n 1

#BSUB -J n1p1o8
##BSUB -o outfile.email
#BSUB -e err

export OMP_NUM_THREADS=8

date
/home/apps/bin/lava.openmpi.wrapper -bynode -x OMP_NUM_THREADS \
    ~/my_program ~/input.dat ~/output.out 
date

我做了一些实验,一台主机上独占。 不过,我不知道该如何解释一些结果。

1。
-n OMP_NUM_THREADS 时间
1 4 21:12
2 4 20:12

这是否意味着MPI在这里并不做任何并行? 我想在第二种情况下每一个MPI进程将有4个线程OMP所以它应该使用800这应该是比第一次更快%的CPU使用率。

另一个结果证明它是
-n OMP_NUM_THREADS 时间
2 2 31:42
4 2 30:47

他们也有八九不离十的运行时间。

2。
在这种情况下,如果我想在此群集与由简单的方式合理的最佳速度为平行这一方案,是它合理把1个MPI处理(告诉LFG,我使用一个核心)在每个主机中,设置OMP_NUM_THREADS = 8,然后独家运行呢? 因此MPI仅适用于跨节点的工作和OpenMP工作在内部节点的工作。 (-N =#主机; ptile = 1; OMP_NUM_THREADS =最大芯中的每个主机)

更新:该项目由gfortran -fopenmp没有mpicc编译。 MPI仅用于分发的可执行文件。

UPDATE Mar.3:程序内存占用监视器

当地环境:苹果10.8 / 2.9 GHz的酷睿i7 / 8GB内存

没有的OpenMP

  • 真正的内存大小:8.4 MB
  • 虚拟内存大小:2.37 GB
  • 共享存储器大小:212 KB
  • 专用内存大小:7.8 MB
  • 虚拟专用内存:63.2 MB

使用OpenMP(4个线程)

  • 真正的内存大小:31.5 MB
  • 虚拟内存大小:2.52 GB
  • 共享存储器大小:212 KB
  • 专用内存大小:27.1 MB
  • 虚拟专用内存:210.2 MB

群集硬件简要信息

每个主机包含双四芯片,其是每个节点和8GB存储器8芯。 此组中的主机由InfiniBand的连接。

Answer 1:

考虑到你的意见已指定的信息,你最好的选择是:

  • 要求独家节点访问-x (你已经这样做);
  • 请求每个节点一个槽与-n 1 (你已经做到这一点);
  • 设置OMP_NUM_THREADS到每个节点的内核数(你已经这样做);
  • 启用OpenMP螺纹结合;
  • 直接启动可执行文件。

你的任务脚本应该是这样的:

#BSUB -q queue_name
#BSUB -x
#BSUB -n 1

#BSUB -J n1p1o8
##BSUB -o outfile.email
#BSUB -e err

export OMP_NUM_THREADS=8
export OMP_PROC_BIND=true

date
~/my_program ~/input.dat ~/output.out
date

OMP_PROC_BIND是OpenMP的3.1规范的一部分。 如果使用编译器粘附到旧版本的标准,你应该使用供应商特定的设置,例如, GOMP_CPU_AFFINITY GCC和KMP_AFFINITY英特尔的编译器。 结合线程核阻止操作系统从周围线程移动不同的处理器核之间,从而加快了执行,尤其是在NUMA系统(例如与多于一个的CPU插座和在每个插座分开的存储器控​​制器的机器),其中数据局部性是非常重要的。

如果您想在不同的输入文件运行程序的多个副本,然后提交阵列作业。 随着LSF(我猜熔岩太),这是通过改变作业脚本来完成:

#BSUB -q queue_name
#BSUB -x
#BSUB -n 1

#BSUB -J n1p1o8[1-20]
##BSUB -o outfile.email
#BSUB -e err_%I

export OMP_NUM_THREADS=8
export OMP_PROC_BIND=true

date
~/my_program ~/input_${LSF_JOBINDEX}.dat ~/output_${LSF_JOBINDEX}.out
date

此提交的20子作业阵列作业( -J n1p1o8[1-20] %I-e由作业编号代替,所以你会得到一个单独err每个作业文件。 所述LSF_JOBINDEX环境变量设置为当前作业索引,即,其将是1在第一作业, 2在第二等等。


我对你的程序的内存占用的问题不是多少内存它消耗。 这是有关如何大是在一个单一的OpenMP循环处理的典型数据集。 如果数据集不是足够小,以适合CPU(S)的最后一级缓存,那么内存带宽来考虑。 如果你的代码确实对每个数据项重本地处理,那么它可能与线程的数量规模。 如果对方确实简单,光处理,那么内存总线可能会甚至由单个线程饱和,特别是如果代码是正确的矢量化。 通常,这是通过在FLOPS /字节的所谓操作强度测量。 它给数据处理的这种情况发生之前,下一个数据元素是从存储器中取出的量。 高的操作强度意味着大量数字运算的CPU中的情形和数据仅很少从存储器传输至/。 这种方案几乎扩展线性的线程数,无论内存带宽是什么。 在另一侧,具有非常低的操作强度码是存储器结合和它们离开未充分利用的CPU。

一种程序,它在很大程度上受内存限制的不与数量的线程,但与现有的内存带宽扩展。 例如,较新的Intel或AMD的系统上,每个CPU插座有它自己的存储器控​​制器和存储器数据通路。 在这样的系统的存储器带宽是单一插座的带宽,例如,一个系统具有两个插座的倍数提供了两倍的单插座系统的存储器带宽。 在这种情况下,你可能会看到改善,只要这两个插座使用,例如,如果你设置的代码运行时OMP_NUM_THREADS等于核心的,或者如果您设置总数OMP_NUM_THREADS等于2 ,并告诉运行时把两个线程上不同的插座(这是当线程正在执行向量化码和单个线程能够以饱和本地存储器总线一个可能的情形)。



文章来源: Hybrid MPI/OpenMP in LSF