Linux的NUMA技术

来源:在阅读关于spark的论文,Understanding the Behavior of Spark Workloads from Linux Kernel Parameters Perspective这篇paper时甚为佩服作者的思路,其中涉及到一个关键点就是linux的NUMA技术,感觉很是新颖,遂google。
趋势:许多厂商都成功推出基于NUMA架构的服务器
本知识笔记从以下总结
1.背景
2.存储管理
3.NUMA调度
4.用户层的API
5.NUMA基本测试

一.背景

传统的SMP(对称多处理器)中,所有处理器都共享系统总线,因此当处理器的数目增大时,系统总线的竞争冲突加大,系统总线将成为瓶颈,所以目前SMP系统的CPU数目一般只有数十个,可扩展能力受到极大限制。NUMA技术有效结合了SMP系统易编程性和MPP(大规模并行)系统易扩展性的特点,较好解决了SMP系统的可扩展性问题,已成为当今高性能服务器的主流体系结构之一。
基于NUMA架构的高性能服务器有HP的Superdome、SGI的Altix 3000、IBM的 x440、NEC的TX7、AMD的Opteron等。(基于参考资料中作者编写时间是04年7月)

二.NUMA存储管理

NUMA系统是由多个结点通过高速互连网络连接而成的,如图1是SGI Altix 3000 ccNUMA系统中的两个结点。

图1 SGI Altix3000系统的两个结点.gif

NUMA系统的结点通常是由一组CPU(如,SGI Altix 3000是2个Itanium2 CPU)和本地内存组成,有的结点可能还有I/O子系统。由于每个结点都有自己的本地内存,因此全系统的内存在物理上是分布的,每个结点访问本地内存和访问其它结点的远地内存的延迟是不同的,为了减少非一致性访存对系统的影响,在硬件设计时应尽量降低远地内存访存延迟(如通过Cache一致性设计等),而操作系统也必须能感知硬件的拓扑结构,优化系统的访存。
目前IA64 Linux所支持的NUMA架构服务器的物理拓扑描述是通过ACPI(Advanced Configuration and Power Interface)实现的。ACPI是由Compaq、Intel、Microsoft、Phoenix和Toshiba联合制定的BIOS规范,它定义了一个非常广泛的配置和电源管理,目前该规范的版本已发展到2.0,3.0o版本正在制定中,具体信息可以从 http://www.acpi.info网站上获得。ACPI规范也已广泛应用于IA-32架构的至强服务器系统中。
Linux对NUMA系统的物理内存分布信息是从系统firmware的ACPI表中获得的,最重要的是SRAT(System Resource Affinity Table)和SLIT(System Locality Information Table)表,其中SRAT包含两个结构:
Processor Local APIC/SAPIC Affinity Structure:记录某个CPU的信息;
Memory Affinity Structure:记录内存的信息;

SLIT表则记录了各个结点之间的距离,在系统中由数组node_distance[ ]记录。
Linux采用Node、Zone和页三级结构来描述物理内存的,如图2所示,
图2 Linux中Node、Zone和页的关系

2.1 结点

Linux用一个struct pg_data_t结构来描述系统的内存,系统中每个结点都挂接在一个pgdat_list列表中,对UMA体系结构,则只有一个静态的pg_data_t结构contig_page_data。对NUMA系统来说则非常容易扩充,NUMA系统中一个结点可以对应Linux存储描述中的一个结点,具体描述见linux/mmzone.h。

typedef struct pglist_data {
zone_t node_zones[MAX_NR_ZONES];
zonelist_t node_zonelists[GFP_ZONEMASK+1];
int nr_zones;
struct page *node_mem_map;
unsigned long *valid_addr_bitmap;
struct bootmem_data *bdata;
unsigned long node_start_paddr;
unsigned long node_start_mapnr;
unsigned long node_size;
int node_id;
struct pglist_data *node_next;
} pg_data_t;

下面就该结构中的主要域进行说明,

系统中所有结点都维护在 pgdat_list 列表中,在 init_bootmem_core 函数中完成该列表初始化工作。

2.2 Zone

每个结点的内存被分为多个块,称为zones,它表示内存中一段区域。一个zone用struct_zone_t结构描述,zone的类型主要有ZONE_DMA、ZONE_NORMAL和ZONE_HIGHMEM。ZONE_DMA位于低端的内存空间,用于某些旧的ISA设备。ZONE_NORMAL的内存直接映射到Linux内核线性地址空间的高端部分,许多内核操作只能在ZONE_NORMAL中进行。例如,在X86中,zone的物理地址如下:

Zone是用struct zone_t描述的,它跟踪页框使用、空闲区域和锁等信息,具体描述如下:

typedef struct zone_struct {
spinlock_t lock;
unsigned long free_pages;
unsigned long pages_min, pages_low, pages_high;
int need_balance;
free_area_t free_area[MAX_ORDER];
wait_queue_head_t * wait_table;
unsigned long wait_table_size;
unsigned long wait_table_shift;
struct pglist_data *zone_pgdat;
struct page *zone_mem_map;
unsigned long zone_start_paddr;
unsigned long zone_start_mapnr;char *name;unsigned long size;
} zone_t;

下面就该结构中的主要域进行说明,



当系统中可用的内存比较少时,kswapd将被唤醒,并进行页交换。如果需要内存的压力非常大,进程将同步释放内存。如前面所述,每个zone有三个阈值,称为pages_low,pages_min和pages_high,用于跟踪该zone的内存压力。pages_min的页框数是由内存初始化free_area_init_core函数,根据该zone内页框的比例计算的,最小值为20页,最大值一般为255页。当到达pages_min时,分配器将采用同步方式进行kswapd的工作;当空闲页的数目达到pages_low时,kswapd被buddy分配器唤醒,开始释放页;当达到pages_high时,kswapd将被唤醒,此时kswapd不会考虑如何平衡该zone,直到有pages_high空闲页为止。一般情况下,pages_high缺省值是pages_min的3倍。
Linux存储管理的这种层次式结构可以将ACPI的SRAT和SLIT信息与Node、Zone实现有效的映射,从而克服了传统Linux中平坦式结构无法反映NUMA架构的缺点。当一个任务请求分配内存时,Linux采用局部结点分配策略,首先在自己的结点内寻找空闲页;如果没有,则到相邻的结点中寻找空闲页;如果还没有,则到远程结点中寻找空闲页,从而在操作系统级优化了访存性能。

三、NUMA调度器

NUMA系统中,由于局部内存的访存延迟低于远地内存访存延迟,因此将进程分配到局部内存附近的处理器上可极大优化应用程序的性能。Linux 2.4内核中的调度器由于只设计了一个运行队列,可扩展性较差,在SMP平台表现一直不理想。当运行的任务数较多时,多个CPU增加了系统资源的竞争,限制了负载的吞吐率。在2.5内核开发时,Ingo Molnar写了一个多队列调度器,称为O(1),从2.5.2开始O(1)调度器已集成到2.5内核版本中。O(1)是多队列调度器,每个处理器都有一条自己的运行队列,但由于O(1)调度器不能较好地感知NUMA系统中结点这层结构,从而不能保证在调度后该进程仍运行在同一个结点上,为此,Eirch Focht开发了结点亲和的NUMA调度器,它是建立在Ingo Molnar的O(1)调度器基础上的,Eirch将该调度器向后移植到2.4.X内核中,该调度器最初是为基于IA64的NUMA机器的2.4内核开发的,后来Matt Dobson将它移植到基于X86的NUMA-Q硬件上。

3.1 初始负载平衡

在每个任务创建时都会赋予一个HOME结点(所谓HOME结点,就是该任务获得最初内存分配的结点),它是当时创建该任务时全系统负载最轻的结点,由于目前Linux中不支持任务的内存从一个结点迁移到另一个结点,因此在该任务的生命期内HOME结点保持不变。一个任务最初的负载平衡工作(也就是选该任务的HOME结点)缺省情况下是由exec()系统调用完成的,也可以由fork()系统调用完成。在任务结构中的node_policy域决定了最初的负载平衡选择方式。

3.2 动态负载平衡

在结点内,该NUMA调度器如同O(1)调度器一样。在一个空闲处理器上的动态负载平衡是由每隔1ms的时钟中断触发的,它试图寻找一个高负载的处理器,并将该处理器上的任务迁移到空闲处理器上。在一个负载较重的结点,则每隔200ms触发一次。调度器只搜索本结点内的处理器,只有还没有运行的任务可以从Cache池中移动到其它空闲的处理器。
如果本结点的负载均衡已经非常好,则计算其它结点的负载情况。如果某个结点的负载超过本结点的25%,则选择该结点进行负载均衡。如果本地结点具有平均的负载,则延迟该结点的任务迁移;如果负载非常差,则延迟的时间非常短,延迟时间长短依赖于系统的拓扑结构。

四、CpuMemSets

SGI的Origin 3000 ccNUMA系统在许多领域得到了广泛应用,是个非常成功的系统,为了优化Origin 3000的性能,SGI的IRIX操作系统在其上实现了CpuMemSets,通过将应用与CPU和内存的绑定,充分发挥NUMA系统本地访存的优势。Linux在NUMA项目中也实现了CpuMemSets,并且在SGI的Altix 3000的服务器中得到实际应用。
CpuMemSets为Linux提供了系统服务和应用在指定CPU上调度和在指定结点上分配内存的机制。CpuMemSets是在已有的Linux调度和资源分配代码基础上增加了cpumemmap和cpumemset两层结构,底层的cpumemmap层提供一个简单的映射对,主要功能是:将系统的CPU号映射到应用的CPU号、将系统的内存块号映射到应用的内存块号;上层的cpumemset层主要功能是:指定一个进程在哪些应用CPU上调度任务、指定内核或虚拟存储区可分配哪些应用内存块。

4.1 cpumemmap

内核任务调度和内存分配代码使用系统号,系统中的CPU和内存块都有对应的系统号。应用程序使用的CPU号和内存块号是应用号,它用于指定在cpumemmap中CPU和内存的亲和关系。每个进程、每个虚拟内存区和Linux内核都有cpumemmap,这些映射是在fork()、exec()调用或创建虚拟内存区时继承下来的,具有root权限的进程可以扩展cpumemmap,包括增加系统CPU和内存块。映射的修改将导致内核调度代码开始运用新的系统CPU,存储分配代码使用新的内存块分配内存页,而已在旧块上分配的内存则不能迁移。Cpumemmap中不允许有空洞,例如,假设cpumemmap的大小为n,则映射的应用号必须从0到n-1。Cpumemmap中系统号和应用号并不是一对一的映射,多个应用号可以映射到同一个系统号。

4.2 cpumemset

系统启动时,Linux内核创建一个缺省的cpumemmap和cpumemset,在初始的cpumemmap映射和cpumemset中包含系统目前所有的CPU和内存块信息。
Linux内核只在该任务cpumemset的CPU上调度该任务,并只从该区域的内存列表中选择内存区分配给用户虚拟内存区,内核则只从附加到正在执行分配请求CPU的cpumemset内存列表中分配内存。
一个新创建的虚拟内存区是从任务创建的当前cpumemset获得的,如果附加到一个已存在的虚拟内存区时,情况会复杂些,如内存映射对象和Unix System V的共享内存区可附加到多个进程,也可以多次附加到同一个进程的不同地方。如果被附加到一个已存在的内存区,缺省情况下新的虚拟内存区继承当前附加进程的cpumemset,如果此时标志位为CMS_SHARE,则新的虚拟内存区链接到同一个cpumemset。
当分配页时,如果该任务运行的CPU在cpumemset中有对应的存储区,则内核从该CPU的内存列表中选择,否则从缺省的CPU对应的cpumemset选择内存列表。

4.3硬分区和CpuMemSets

在一个大的NUMA系统中,用户往往希望控制一部分CPU和内存给某些特殊的应用。目前主要有两种技术途径:硬分区和软分区技术,CpuMemSets是属于软分区技术。将一个大NUMA系统的硬分区技术与大NUMA系统具有的单系统映像优势是矛盾的,而CpuMemSets允许用户更加灵活的控制,它可以重叠、划分系统的CPU和内存,允许多个进程将系统看成一个单系统映像,并且不需要重启系统,保障某些CPU和内存资源在不同的时间分配给指定的应用。
SGI的CpuMemSets软分区技术有效解决硬分区中的不足,一个单系统的SGI ProPack Linux服务器可以分成多个不同的系统,每个系统可以有自己的控制台、根文件系统和IP网络地址。每个软件定义的CPU组可以看成一个分区,每个分区可以重启、安装软件、关机和更新软件。分区间通过SGI NUMAlink连接进行通讯,分区间的全局共享内存由XPC和XPMEM内核模块支持,它允许一个分区的进程访问另一个分区的物理内存。

五、测试

为了有效验证Linux NUMA系统的性能和效率,我们在SGI公司上海办事处测试了NUMA架构对SGI Altix 350性能。
该系统的配置如下: CPU:8个1.5 GHz Itanium2 内存:8GB 互连结构:如图3所示
图3 SGI Altix350 4个计算模块的Ring拓扑

image.png

测试用例:
1、Presta MPI测试包(来自ASCI Purple的Benchmark)
从互连拓扑结构可以看出,计算模块内部的访存延迟不需要通过互连,延迟最逗,剩下的需要通过1步或2步互连到达计算模块,我们通过Presta MPI测试包,重点测试每步互连对系统的影响,具体结果如下:

2、NASA的NPB测试

上述测试表明,SGI Altix 350系统具有较高的访存和计算性能,Linux NUMA技术已进入实用阶段。
参考资料

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容

  • Linux 内核SMP负载均衡浅析 需求在《linux进程调度浅析》一文中提到,在SMP(对称多处理器)环境下,每...
    meng_philip123阅读 1,779评论 0 3
  • Java8张图 11、字符串不变性 12、equals()方法、hashCode()方法的区别 13、...
    Miley_MOJIE阅读 3,681评论 0 11
  • /proc下的字文件及子文件夹的解释: /proc 文件系统是 GNU/Linux 特有的。它是一个虚拟的文件系统...
    Regin阅读 1,706评论 1 2
  • 细雨纷纷月无光,冷落无声落花伤,嫦娥应悔空对月,不识人间鬼魍魉。中秋之夜心绝望,咫尺天涯不牵强!
    文卷阅读 194评论 0 1
  • 诱惑 像一个我爱的坏人 不可,偏无不可 任我苦口婆心劝诫万千回 终不敌你温柔叫唤半声多 沦陷,又再沦陷 挣扎在时光...
    小小七阅读 246评论 0 3