共享内存多处理器架构在过去几十年的演变
8 分钟阅读
非统一内存访问 (NUMA) 是当今多处理系统中使用的共享内存架构。每个 CPU 都分配有自己的本地内存,并且可以从系统中的其他 CPU 访问内存。本地内存访问提供低延迟 - 高带宽性能。而访问另一个 CPU 拥有的内存具有更高的延迟和更低的带宽性能。现代应用程序和操作系统(如 ESXi)默认支持 NUMA,但要提供最佳性能,虚拟机配置应在考虑 NUMA 架构的情况下完成。如果设计不正确,则该特定虚拟机或在该 ESXi 主机上运行的所有 VM 的最坏情况下都会出现意外行为或整体性能下降。 本系列旨在深入介绍 CPU 架构、内存子系统以及 ESXi CPU 和内存调度程序。允许您创建一个高性能平台,为更高的服务和更高的整合率奠定基础。在我们了解现代计算架构之前,回顾一下共享内存多处理器架构的历史有助于理解我们今天使用 NUMA 系统的原因。
在设计一致的低延迟、高带宽平台时,似乎称为统一内存访问的架构更适合。然而,现代系统架构将限制它真正统一。要了解这背后的原因,我们需要回顾历史以确定并行计算的关键驱动因素。 随着七十年代初期关系数据库的引入,对能够为多个并发用户操作和过多数据生成提供服务的系统的需求成为主流。尽管单处理器性能令人印象深刻,但多处理器系统能够更好地处理这种工作负载。为了提供具有成本效益的系统,共享内存地址空间成为研究的重点。早期,提倡使用交叉开关的系统,但是随着这种设计的复杂性随着处理器的增加而增加,这使得基于总线的系统更具吸引力。允许总线系统中的处理器通过在总线上发送请求来访问整个内存空间,这是一种尽可能最佳地使用可用内存的非常经济有效的方式。
然而,基于总线的系统有其自身的可扩展性问题。主要问题是带宽有限,这限制了总线可以容纳的处理器数量。将 CPU 添加到系统会引入两个主要的关注领域:
- 每个节点的可用带宽随着每个 CPU 的增加而减少。
- 添加更多处理器时,总线长度会增加,从而增加延迟。
CPU 的性能增长,特别是处理器和内存性能之间的速度差距,过去是,现在仍然是,对多处理器来说是毁灭性的。由于预计处理器和内存之间的内存差距会增加,因此人们投入了大量精力来开发有效的策略来管理内存系统。其中一项策略是添加内存缓存,这带来了许多挑战。解决这些挑战仍然是当今 CPU 设计团队的主要关注点,对缓存结构和复杂算法进行了大量研究以避免缓存未命中。
缓存监听协议介绍
为每个 CPU 附加一个缓存可以在很多方面提高性能。使内存更靠近 CPU 可以减少平均内存访问时间,同时减少内存总线上的带宽负载。在共享内存架构中为每个 CPU 添加缓存的挑战在于它允许内存块的多个副本存在。这称为缓存一致性问题。为了解决这个问题,发明了缓存侦听协议,试图创建一个模型来提供正确的数据,同时又不会耗尽总线上的所有带宽。最流行的协议 write invalidate 在写入本地缓存之前擦除所有其他数据副本。其他处理器对该数据的任何后续读取都将检测到其本地缓存中的缓存未命中,并且将从包含最近修改的数据的另一个 CPU 的缓存中提供服务。这种模型节省了大量总线带宽,并允许统一内存访问系统在 1990 年代初期出现。第 3 部分更详细地介绍了现代缓存一致性协议。
统一内存访问架构
对系统中任何内存模块的访问时间相同(统一)的基于总线的多处理器的处理器通常称为统一内存访问 (UMA) 系统或对称多处理器 (SMP)。 对于 UMA 系统,CPU 通过系统总线(前端总线)连接到北桥。北桥包含内存控制器,所有进出内存的通信都必须通过北桥。负责管理所有设备的 I/O 的 I/O 控制器连接到北桥。因此,每一个I/O都必须经过北桥才能到达CPU。
多个总线和内存通道用于使可用带宽加倍并减少北桥的瓶颈。为了进一步增加内存带宽,一些系统将外部内存控制器连接到北桥,从而提高带宽并支持更多内存。然而,由于北桥的内部带宽和早期 snoopy 缓存协议的广播性质,UMA 被认为具有有限的可扩展性。随着当今高速闪存设备的使用,每秒推动数十万次 IO,他们完全正确地认为这种架构无法扩展以适应未来的工作负载。
非统一内存访问架构
为了提高可伸缩性和性能,对共享内存多处理器架构进行了三个关键更改;
- 非统一内存访问组织
- 点对点互连拓扑
- 可扩展的缓存一致性解决方案
1:非统一内存访问组织
NUMA 摆脱了集中式内存池并引入了拓扑属性。通过根据从处理器到内存的信号路径长度对内存位置进行分类,可以避免延迟和带宽瓶颈。这是通过重新设计处理器和芯片组的整个系统来完成的。NUMA 架构在 90 年代末流行起来,当时它被用于 SGI 超级计算机,例如Cray Origin 2000。NUMA 帮助识别内存的位置,在这些系统的这种情况下,他们不得不想知道哪个机箱中的哪个内存区域保存内存位。
在千禧年的上半叶,AMD 将 NUMA 带入了 UMA 系统至高无上的企业环境。2003 年推出了 AMD Opteron 系列,其特点是集成内存控制器,每个 CPU 都拥有指定的内存条。每个 CPU 现在都有自己的内存地址空间。NUMA 优化操作系统(如 ESXi)允许工作负载从两个内存地址空间消耗内存,同时优化本地内存访问。让我们使用双 CPU 系统的示例来阐明单个系统中本地和远程内存访问之间的区别。
连接到 CPU1 的内存控制器的内存被认为是本地内存。连接到另一个 CPU 插槽 (CPU2) 的内存对于 CPU1 来说被认为是外部的或远程的。远程内存访问比本地内存访问有额外的延迟开销,因为它必须遍历互连(点对点链接)并连接到远程内存控制器。由于内存位置不同,该系统会经历“不一致”的内存访问时间。
2:点对点互连
AMD 通过AMD Opteron 微架构引入了点对点连接 HyperTransport 。英特尔于 2007 年通过在其 Nehalem 处理器系列设计中引入QuickPath 架构而放弃了其双独立总线架构。
Nehalem架构是英特尔微体系结构中的重大设计变更,被认为是英特尔酷睿系列的第一代。当前的 Broadwell 架构是英特尔酷睿品牌的第 4 代(英特尔至强 E5 v4),最后一段包含了更多关于微架构世代的信息。在 QuickPath 架构中,内存控制器移至 CPU,并引入了 QuickPath 点对点互连 (QPI) 作为系统中 CPU 之间的数据链路。
Nehalem 微架构不仅取代了传统的前端总线,而且将整个子系统重组为服务器 CPU 的模块化设计。这种模块化设计被称为“Uncore”,并创建了一个用于缓存和互连速度的构建块库。移除前端总线改善了带宽可扩展性问题,但在处理大量内存容量和带宽时必须解决处理器内和处理器间通信。集成内存控制器和 QuickPath 互连都是 Uncore 的一部分,并且是模型特定寄存器 (MSR)。它们连接到提供处理器内和处理器间通信的 MSR。Uncore 的模块化还允许英特尔提供不同的 QPI 速度,在编写英特尔 Broadwell-EP 微架构(2016)时提供 6。每秒 4 千兆传输 (GT/s)、8.0 GT/s 和 9.6 GT/s。分别在CPU之间提供25.6 GB/s、32 GB/s和38.4 GB/s的理论最大带宽。从这个角度来看,最后使用的前端总线提供了 1.6 GT/s 或 12.8 GB/s 的平台带宽。在引入 Sandy Bridge 时,Intel 将 Uncore 重新命名为 System Agent,但当前文档中仍使用术语 Uncore。您可以在第 2 部分中找到有关 QuickPath 和 Uncore 的更多信息。然而,术语 Uncore 仍在当前文档中使用。您可以在第 2 部分中找到有关 QuickPath 和 Uncore 的更多信息。然而,术语 Uncore 仍在当前文档中使用。您可以在第 2 部分中找到有关 QuickPath 和 Uncore 的更多信息。
3:可扩展的缓存一致性
每个核心都有一个通往 L3 缓存的专用路径。每条路径都由一千根电线组成,你可以想象,如果你想减少纳米制造工艺,同时增加要访问缓存的内核,这将无法很好地扩展。为了能够扩展,Sandy Bridge Architecture 将 L3 缓存从 Uncore 中移出,并引入了可扩展的环形片上互连。这允许 Intel 将 L3 高速缓存划分和分布在相等的片中。这提供了更高的带宽和关联性。每个切片为 2.5 MB,一个切片与每个核心相关联。该环还允许每个内核访问其他所有切片。下图是 Broadwell 微架构 (v4) (2016) 的低核心数 (LCC) Xeon CPU 的芯片配置。
这种缓存架构需要一个监听协议,该协议结合了分布式本地缓存和系统中的其他处理器,以确保缓存一致性。随着系统中内核的增加,窥探流量会增加,因为每个内核都有自己稳定的缓存未命中流。这会影响 QPI 链接和末级缓存的消耗,需要不断开发探听一致性协议。第 3 部分将深入介绍 Uncore、可扩展环形片上互连以及缓存侦听协议对 NUMA 性能的重要性。
非交错启用 NUMA = SUMA
物理内存分布在主板上,但是,系统可以通过在两个 NUMA 节点之间交错内存来提供单个内存地址空间。这称为节点交错(设置在第 2 部分中介绍)。启用节点交错后,系统将成为足够统一的内存架构 (SUMA)。系统不是将系统中处理器和内存的拓扑信息和性质中继到操作系统,而是将整个内存范围分解为 4KB 可寻址区域,并以循环方式从每个节点映射它们。这提供了一种“交错式”内存结构,其中内存地址空间分布在节点之间。
有趣的是,SUMA 系统提供了统一的内存访问时间。只是不是最佳的,并且在很大程度上取决于 QPI 体系结构中的竞争级别。Intel Memory Latency Checker用于演示同一系统上 NUMA 和 SUMA 配置之间的差异。
此测试测量系统中从每个套接字到另一个套接字的空闲延迟(以纳秒为单位)。Socket 0 报告的内存节点0 的延迟是本地内存访问,内存节点1 的socket 0 的内存访问是配置为NUMA 的系统中的远程内存访问。
正如预期的那样,交织受到不断遍历 QPI 链接的影响。空闲内存测试是最好的情况,一个更有趣的测试是测量加载延迟。如果您的 ESXi 服务器处于空闲状态,那将是一项糟糕的投资,因此您可以假设 ESXi 系统正在处理数据。测量负载延迟可以更好地了解系统在正常负载下的性能。在测试期间,负载注入延迟每 2 秒自动更改一次,并且带宽和相应的延迟都是在该级别测量的。本次测试使用100%读取流量。左侧为NUMA测试结果,右侧为SUMA测试结果。
与配置为 NUMA 的系统相比,SUMA 系统报告的带宽较低,同时保持较高的延迟。因此,重点应该放在优化 VM 大小上以利用系统的 NUMA 特性。
Nehalem & Core 微架构概述
随着 2008 年 Nehalem 微架构的推出,英特尔放弃了 Netburst 架构。Nehalem 微架构向英特尔客户介绍了 NUMA。多年来,英特尔根据其著名的 Tick-Tock 模型引入了新的微体系结构和优化。每一次 Tick 都会进行优化,缩小工艺技术,每一次 Tock 都会引入新的微体系结构。尽管 Intel 自 2012 年以来提供了一致的品牌模型,但人们倾向于使用 Intel 架构代号来讨论 CPU tick 和 tock 世代。即使 EVC 基线也列出了这些内部英特尔代号,品牌名称和架构代号将在本系列中使用:
接下来,第 2 部分:系统架构
NUMA 深度剖析系列:
- 第 0 部分: 介绍 NUMA 深度剖析系列
- 第 1 部分:从 UMA 到 NUMA
- 第 2 部分:系统架构
- 第 3 部分:缓存一致性
- 第 4 部分:本地内存优化
- 第 5 部分:ESXi VMkernel NUMA 构造