大连人工智能计算平台——华为昇腾AI平台——高性能计算HPC的CPU亲和性设置--affinity_负载均衡

 

大连人工智能计算平台——华为昇腾AI平台——高性能计算HPC的CPU亲和性设置--affinity_负载均衡_02

 

 

大连人工智能计算平台——华为昇腾AI平台——高性能计算HPC的CPU亲和性设置--affinity_负载均衡_03

 

 

 

很不幸的是课题组没有经费了,这个超算账号已然被华为官方停掉了,想想自己囊中羞涩还是一切作罢,估计关于超算方面的东西也就快分享到这里了。

 

 

====================================================

 

要了解超算平台CPU的亲和性设置就需要知道几个概念:socket、numa node、core、processor,

给出自己对这几个概念的不准确理解:

socket是指一个主板上一共插了几块物理CPU;

numa node是指所有主板上的CPU中划分的numa节点;

core是指计算核心,如果开启超线程的情况下一个物理core可以有两个processors;

Thread(s)/processor(s): 进程的具体的运行逻辑单位;

 

lscpu 查询CPU参数:

大连人工智能计算平台——华为昇腾AI平台——高性能计算HPC的CPU亲和性设置--affinity_超线程_04

 

 

numactl 查询CPU的numa拓扑结构:

大连人工智能计算平台——华为昇腾AI平台——高性能计算HPC的CPU亲和性设置--affinity_杂谈_05

 

 

 

=========================================================

 

 

理论上,一个socket,也就是一个物理CPU是可以有多个numa节点的,但是实际中我个人所知道的所有CPU都是一个socket对应一个numa节点的,这里不包括虚拟机中自设置的numa节点,这里指的都是物理形式下的numa节点。

一般可以这么理解,一个socket有一个numa node,而一个numa node有若干个core,而如果开启超线程的情况下一个core有两个thread,如果没有开启超线程的情况下一个core只有一个thread。

 

 

 

关于亲和性的作用:

https://support.huawei.com/enterprise/zh/doc/EDOC1100216760/3e3f483e


大连人工智能计算平台——华为昇腾AI平台——高性能计算HPC的CPU亲和性设置--affinity_超线程_06

 

大连人工智能计算平台——华为昇腾AI平台——高性能计算HPC的CPU亲和性设置--affinity_超线程_07

 

大连人工智能计算平台——华为昇腾AI平台——高性能计算HPC的CPU亲和性设置--affinity_超线程_08

 

 

 

 

个人经验:

在设置mpi的亲和性时最好不要对socket进行设置而是直接对numa进行设置,因为即使对socket也是要和numa保持一致的(现在用到的CPU都是一个socket对应一个numa node),因此我们如果设置亲和性只需要设置numa和core即可。

 

 

 

具体案例:

官方给出的demo:

https://support.huawei.com/enterprise/zh/doc/EDOC1100216760/3e3f483e

针对这个资料给出一些补充:

1.  -aff 和 -R 一样针对的不是job而是task,也就是说这个设置是给一个job下的所有副本(task)中所申请的CPU(-R 参数)所设置的亲和性;

2. 超算平台一般情况下是不开超线程的,这里官方给出的案例都是开启超线程的,也就是一个core对应两个threads;

3. any的分布策略是遍历的,那么具体形式没有给出,比如:

场景描述

用户环境为两个节点,资源CPU拓扑如下所示。

node1拓扑信息:

socket(0)
  numa(0) [memory = 7820 M]
    core(0): thread(0,1)
    core(1): thread(2,3)

node2拓扑信息:

socket(0)
  numa(0) [memory = 16383 M]
    core(0): thread(0,1)
    core(1): thread(2,3)
    core(2): thread(4,5)
    core(3): thread(6,7)
socket(1)
  numa(1) [memory = 16384 M]
    core(4): thread(8,9)
    core(5): thread(10,11)
    core(6): thread(12,13)
    core(7): thread(14,15)

操作步骤

示例三:绑定策略为any

提交作业命令:dsub -aff "numa[count=2,distribution=any] core[count=4]" -R "cpu=8" sleep 100

调度匹配流程说明:

  1. 依据请求资源总量过滤节点,由于节点node1总剩余资源量或总资源量不足以运行此作业,因此过滤掉节点node1。
  2. node2剩余总资源量满足需求量,再进一步进行亲和需求匹配。
  3. 从请求信息看作业需求两个numa节点,同时匹配策略采用any分配策略,即不进行优选,直接按计算单元索引进行分组匹配;同时作业将分散到4个core上,同样采样负载均衡balance策略方式进行资源绑定。     
  4. 最终匹配绑定的thread信息为0、1、2、3、8、9、10、11八个超线程。

 针对上面的第2步,对numa的选择使用的是any策略,个人理解是先使用balance策略分配,如果分配失败则使用pack策略。

 

 

 

PS: 正如前面提到的,-R 和 -aff 都是针对task的,而不是针对job的,也就是说这个参数是为副本所设置的,由于副本(task)的所有进程必须运行在同一台主机上,所以采用了上面的分配策略;也由于副本(task)必须运行在同一个主机上,而现在的超算平台其主机上的CPU基本都是双物理CPU的,并且每个物理CPU都只有一个numa节点,也就是说如果同时设置socket和numa那么必然只有socket[count=1]numa[count=1]或socket[count=2]numa[count=2]两种形式,同时由于在一定程度上(一个socket只对应一个numa node),因此最好的方法就是只设置numa参数即可,即numa[count=1]或numa[count=2]两种形式。

由于numa的设置只有numa[count=1]或numa[count=2]两种形式,那么我们只需要保证core的参数和numa的参数乘积等于-R中CPU的参数,如:

-R “cpu=8”

那么可以有下面两种有效设置:

numa[count=1]core[count=8]

或 

numa[count=2]core[count=4]

 

 

 

 

==========================================================

 

参考:

https://support.huawei.com/enterprise/zh/doc/EDOC1100216760/3e3f483e