查看原文
其他

Sub-NUMA Clustering

常华Andy Andy730 2024-03-16

Source: Frank Denneman, Sub-NUMA Clustering, September 21, 2022

我注意到一个趋势,即更多的 ESXi 主机启用了Sub-NUMA 集群。通常,此设置用于高性能计算或电信运营商领域,在这些场景里,他们需要减少每一毫秒的延迟,并挤出系统可以提供的每一点带宽。此类工作负载大多经过高度优化并在受控环境中运行,而 ESXi 服务器通常运行组织中可以想象到的每种类型的工作负载的集合。让我们来探索 Sub-NUMA 集群的作用,看看是否应该在您的环境中启用它,它是否有意义。

NUMA

大多数数据中心服务器系统都是 NUMA 系统。在 NUMA 系统中,每个 CPU 都包含自己的内存控制器,这些控制器提供对本地连接内存的访问。全球数据中心的绝大多数系统都是双插槽系统。每个CPU都可以通过其自己的内存控制器访问本地内存容量,但它也可以访问由远程CPU连接和控制的内存。读取和写入本地和远程内存之间的延迟和带宽存在差异,因此称为非一致性内存访问 (NUMA,Non-Uniform Memory Access)。

 AMD EPYC 霄龙架构是一种多芯片模块 (MCM,Multi-Chip-Module)架构,与单片架构及其 I/O 路径行为有很大不同。Sub-NUMA 集群是英特尔 CPU 的功能。AMD 提供了类似的功能,称为“每插槽 NUMA (NPS,NUMA per Socket)”。本文仅重点介绍英特尔 Sub-NUMA 集群技术,因为我目前尚未看到服务器供应商默认启用 NPS 设置。 


逻辑分区

英特尔 E5-2600 处理器家族采用环形架构,允许英特尔进一步优化 CPU 内核到内存的访问。在 Haswell 版本 (v3) 中,英特尔引入了芯片上集群 (COD,Cluster-On-Die)功能。COD 在逻辑上将 CPU 拆分为两个 NUMA 节点。

COD 功能可减少内存层次结构的搜索域。NUMA 系统是缓存一致的。当内核生成内存请求时,它会检查其本地 L1 和 L2 缓存、共享 L3 缓存 (LLC)和远程 CPU 缓存。通过沿着其“自然”环结构屏障拆分CPU,您最终会得到一个更小的内存域来搜索是否存在缓存未命中。最重要的是,如果应用程序和操作系统经过 NUMA 优化,则本地内存流量应该会更少。请查看 NUMA 深入探讨(https://frankdenneman.nl/2016/07/07/numa-deep-dive-part-1-uma-numa/)或阅读这篇(https://www.researchgate.net/publication/279660275_Cache_Coherence_Protocol_and_Memory_Performance_of_the_Intel_Haswell-EP_Architecture)关于 COD 缓存结构的研究论文以获取更多信息。Skylake 架构(英特尔至强可扩展处理器)摆脱了环形架构,引入了网状架构。逻辑分区功能仍然存在,并以新名称 Sub-NUMA 集群 (SNC,Sub-NUMA Clustering)引入。

启用 SNC 后,前面显示的双 CPU 插槽 ESXi 主机系统现在是一个四 NUMA 节点系统。


SNC与NUMA的性能比较

SNC 是隐藏在 BIOS 中的涡轮增压功能吗?如果您查看某些供应商使用的描述,则需要立即启用它。戴尔和联想描述SNC:“...它改善了LLC的平均延迟“。我使用的是 Hadar Greinsmark 在他的研究“Effective Task Scheduling of In-Memory Databases on a Sub-NUMA Processor Topology(https://www.diva-portal.org/smash/get/diva2:1424397/FULLTEXT01.pdf)”中发表的性能数据。在默认 NUMA 配置(SNC 禁用)中,让我们看一下Socket 0 (S0)和Socket 1 (S1)之间的延迟差异。

Latency  (ns)NUMA Node 0 (S0)NUMA Node 1 (S1)
NUMA Node 080.8138.9
NUMA Node 1139.779.9

启用 SNC 后,Socket 0 包含两个 NUMA 节点 0 和 1。Socket 1 包含 NUMA 节点 2 和 3。这些逻辑分区是真正的 NUMA 节点。尽管不同的内存控制器和缓存域位于同一芯片上,但内存控制器的缓存机制和非交错会在域之间创建非统一的内存访问模式。因此,从位于同一Socket内的其他“远程”NUMA 节点获取内存时,延迟会增加。

Latency  (ns)NUMA Node 0 (S0)NUMA Node 1 (S0)NUMA Node 2 (S1)NUMA Node 3 (S1)
NUMA Node 0 (S0)74.2 (-7.5%)81.5 (+0.8%)132.0 (-5%)142.1 (+2.3%)
NUMA Node 1 (S0)82.0 (+1.4%)76.4 (-5.4%)135.6 (-2.4%)144.5 (+4%)
NUMA Node 2 (S1)132.4 (-5.2%)142.0 (+1.7%)73.6 (-7.9%)81.5 (+2%)
NUMA Node 3 (S1)136.0 (-2.6%)144.4 (+3.4%)81.5 (+2%)76.6 (-4.1%)

从本地内存控制器到最近的 LLC 的内存地址的 SNC 映射方法肯定适用于本地 NUMA 延迟,与默认 NUMA 配置相比,SNC 平均下降 6% 到 7%。以 NUMA 节点 0 为例。启用SNC后,它会遇到74.2ns的内存延迟;与禁用的 SNC 相比,访问延迟为 80.8ns。因此,SNC 专门将 NUMA 节点 0 的内存延迟降低了 7.5%。 

性能数字显示,由节点 0 和节点 2 处理的远程连接的性能优于 SNC 禁用状态下的性能,而 NUMA 节点 1 和节点 3 的性能低于 SNC 禁用状态下的性能。报告给同一Socket上的远程节点的延迟数非常有趣。它可能显示了互连体系结构的迷人行为。但是,英特尔不共享有关超级路径互连 (UPI,Ultra Path Interconnect)框架的详细信息。 

如果我们看一下体系结构图,我们注意到在 NUMA 节点 0 之上,存在一个具有两个 UPI 连接的控制器。在 NUMA 节点 1 之上,控制器位于具有单个 UPI 连接的位置。可能单个 UPI 在网格上会遇到更多的阻塞 I/O 流量,而具有两个连接的 UPI 控制器具有更多方法来更好地管理流。

但这只是我纯粹的猜测。如果我们查看绝对的远程I/O数字,则延迟会激增。重要的是,如果工作负载无法在本地读取或写入内存,则它们会执行远程 I/O 操作。如果它可以在位于同一Socket上的 NUMA 节点中找到内存,则会看到延迟增加 8.6%。当它穿过互连传输到另一个Socket中的 NUMA 节点时,延迟增加到 78.2%。当它需要移动到最远的 NUMA 节点时,延迟几乎翻倍 (90%)。默认 NUMA 系统的平均远程延迟命中率为 73%。但 SNC 具有更广泛的性能分布,因为它在本地平均提高了 7%,但也将远程内存访问降级了 5%。让我们来比较一下。在默认情况下,本地访问为 80ns,远程访问为 138.9ns。使用SNC,它必须处理73.6ns与142.0的最坏情况。这就是绩效差距扩大到92.9%的原因。是什么决定了哪些工作负载成为本地和远程工作负载?这是本文的关键。但在我们深入研究之前,让我们先看一下带宽性能。


带宽

您的Skylake CPU 型号具有两个或三个 UPI 链路。每个UPI链路都是点对点全双工连接,每个方向都有单独的通道。UPI 链路的理论传输速度为每秒 1040 亿次传输(GT/s),相当于每秒 20.8 千兆字节(GB/s)。报告中使用的英特尔至强铂金 8180 处理器包含三个 UPI 链路,可能提供 62.4 GB/s 的聚合理论带宽。一个控制器有两个 UPI 链路,另一个控制器有一个 UPI 链路。该研究论文表明,与远程节点通信时,平均带宽约为34.4 GB/s。 


推测

由于有关 UPI 通信模式的有限信息可用,因此我假设系统在默认 NUMA 节点中仅使用两个 UPI 链路。使用默认 NUMA,内存在内存控制器之间交错;因此, 必须从两个内存控制器中检索内存,因此,系统使用两个UPI控制器。为什么它不使用所有三个链路,我认为跨三个链路同步I/O操作并允许其他操作使用互连的开销超过了额外上行链路的潜在好处。 


/推测

但让我们坚持事实。在这里,您可以看到远程内存访问的影响。在默认 NUMA 系统上执行远程 I/O 时,带宽性能会下降 69%。正是出于这个原因,你希望拥有 NUMA 优化的工作负载或大小合适的虚拟机。为什么进度条在屏幕上不线性移动?可能是一些非 NUMA 优化的代码从远程 NUMA 节点获取内存。 

Bandwidth  (MB/s)NUMA Node 0 (S0)NUMA Node 1 (S1)
NUMA Node 0111 08334 451
NUMA Node 134 455111 619

启用 SNC 后,系统将停止在 CPU 封装内的两个内存控制器之间交错整个内存范围,并为每个内存控制器分配内存范围的子集。每个内存控制器都有三个通道,将 NUMA 节点的带宽分成两半。该测试系统使用 DDR4 2666 MHz (21.3 GB/s) 内存模块, 理论上每个 SNC NUMA 节点 提供 高达 63.9 GB/s 的 内存。在查看研究结果时,默认的 NUMA 节点通过启用 SNC 提供 111 GB/s(6 个通道),这应该导致每个 NUMA 节点大约 55.5 GB/s。然而,测试结果报告为 58 GB/s.SNC,由于工作负载的隔离,SNC 将本地带宽平均提高了 4.5%,因此减少了网格上其他 I/O 操作的阻塞时刻。同一Socket上的 NUMA 节点也会有类似的改进。

Bandwidth  (MB/s)NUMA Node 0 (S0)NUMA Node 1 (S0)NUMA Node 2 (S1)NUMA Node 3 (S1)
NUMA Node 0 (S0)58 08758 12334 25434 239
NUMA Node 1 (S0)58 14558 01334 26634 235
NUMA Node 2 (S1)34 28834 24858 06458 147
NUMA Node 3 (S1)34 28834 25458 14558 007

因此,SNC 是为高度优化的工作负载挤出最后一点性能的好方法。如果工作负载从核心计数和内存容量适合较小的 NUMA 节点,则预计延迟将提高 7%,内存带宽将提高 4%。但是,还有一个很大的但是,但不是Sir Mix-a-Lot喜欢的方式。但前提是部署横向扩展工作负载。如果可以在运行单独工作负载的每个工作线程节点中部署两个工作线程,则他们都可以从额外的可获取带宽中受益。如果只部署单个工作负载,则只是抢走了该工作负载可获取带宽的一半。工作负载可以访问远程内存容量,并可能获得更多带宽。不过,由 NUMA 计划程序或应用程序自行决定是否进行智能移动并选择正确的 NUMA 节点。这就是我们到达岔路口的一点,即裸机上的专用工作负载与处理必须考虑多个工作负载的 NUMA 调度程序之间的区别。

SNC 可有效减少每个 NUMA 节点的容量,从而减少单个 NUMA 节点虚拟机大小的边界。我有一个问题:横向扩展工作负载的带宽提高 4%, 延迟提高 7% 听起来是否像您希望在虚拟化平台上启用的内容?如何将 10 个 vCPU VM 放置在每个 CPU 包系统具有 18 个内核的双插槽上?


单个 NUMA 节点虚拟机大小调整

并非每个应用程序都可识别 NUMA。大多数平台操作员和管理团队都试图“调整”虚拟机的大小以规避此问题。适当调整大小意味着 VM 包含的 vCPU 和内存容量少于 CPU 插槽包含的 CPU 核心和内存容量,但仍可正常运行。使用 SNC 时,NUMA 节点会被分成两半,从而在需要放入单个 NUMA 节点时生成更小的虚拟机。 


vNUMA 拓扑

如果虚拟机包含的 vCPU 数多于 NUMA 节点包含的 CPU 核心数,则 ESXi 中的 NUMA 调度程序将为此虚拟机创建一个 vNUMA 拓扑,并将其公开给客户机操作系统以进行 NUMA 优化。NUMA 计划程序为此 VM 创建多个 NUMA 客户端并相应地放置这些客户端,这是了解为什么应该在环境中启用或不应该启用 SNC 的关键。


初始放置

如果虚拟机已打开电源或通过 DRS 将虚拟机迁移到主机中,则 NUMA 计划程序将收到初始放置请求。在初始放置操作期间,NUMA 计划程序会知道 NUMA 节点之间的距离。它将尝试优化 VM 的 NUMA 客户端的位置。换句话说,它尝试将 NUMA 客户端放置在尽可能靠近的位置。因此,大多数情况下,如果 VM 由两个 NUMA 客户端组成,则两个 NUMA 客户端都放置在 NUMA 节点上,这些节点共享启用了 SNC 的同一Socket。

通常,在每次综合测试期间都会发生这种情况,其中此 VM 是在主机上运行的唯一 VM,因此,NUMA 计划程序不必处理争用或复杂的难题,也不必将这些新客户端与其他繁忙的 44 个 NUMA 客户端放在一起。 


NUMA 负载平衡

虚拟机管理程序是一个非常动态的环境。CPU 调度程序必须处理各种工作负载模式,并且存在负载关联和负载同步性等工作负载模式。使用负载关联时,计划程序必须处理由不同计算机上运行的工作负载之间的关系生成的负载峰值。NUMA 计划程序每 2 秒检查一次 CPU 负载,以捕获这些模式。例如,具有前端 VM 的应用程序与数据库通信。随着负载同步性工作负载趋势在一起,每天早上启动多个桌面的 VDI 环境将导致持续的负载峰值。因此,NUMA 负载平衡器可能会决定最好在系统中移动一些 NUMA 客户端。对于本文来说,深入了解 NUMA 负载平衡算法的详细信息太深入了。我在 NUMA 深入探讨中介绍了最多的内容。但要了解的关键是,如果有必要移动 NUMA 客户端,它将移动 NUMA 客户端,但不会考虑距离。对于系统来说,尝试将是最明智的做法,但对于 VM 来说,它可能并不总是最好的。 

在许多情况下, 如果不 启用 SNC,则该 VM 将适合单个 NUMA 节点,并且不会发生远程访问,因为它适合单个 NUMA 节点。使用 SNC 时,大型虚拟机可能大于 SNC-NUMA 节点大小,因此会被拆分。如果此 VM 连接到 PCIe 设备(如 GPU),情况会更糟。批量数据传输可能跨互连进行,从而在主机到设备内存传输操作期间创建不一致的数据加载行为。在此处了解有关 NUMA PCI-e 位置的更多信息。



默认启用 SNC

我为什么要说这个话?我发现 HP 通过工作负载配置文件“虚拟化 – 最大性能”和“常规吞吐量计算”启用了 SNC。

ESXi 在 UI 中没有显示是否启用了 SNC 的设置,但我们可以应用美丽的演绎艺术形式。通过在 ESXi 主机上通过 SSH 运行以下(不受支持的)命令  :

echo "CPU Packages";vsish -e dir /hardware/cpu/packageList;echo "NUMA nodes";vsish -e dir /hardware/cpuTopology/numa/nodes

您将获得 CPU 包数量(您可以手中包含 CPU 内核、内存控制器和 PCI 控制器的设备的名称)和系统中 NUMA 节点数量的列表。如果禁用了 SNC,则 NUMA 节点数应等于 CPU 包数。在这种情况下,SNC 已启用。在大多数系统中,您可以单独启用和禁用该设置,但如果它是配置文件的一部分(例如在HP系统上),则需要对其进行自定义。Dan在推特上发布了执行此操作的方法。 


免责声明!

请注意,本文不是 VMware 关于关闭 SNC 的官方建议。本文将帮助您了解 SNC 对 SNC 在硬件层上的整体行为的影响,以及 ESXi NUMA 调度程序的工作方式。在更改生产环境之前,请始终在正常运行条件下测试环境中的设置和工作负载。


我个人对 SNC 的看法

我相信 SNC 对于运行所有类型工作负载的虚拟化平台来说,几乎没有什么可提供的。工作负载范围从小型到巨型虚拟机。如果您有一个专用的 vSphere 平台运行需要运行的特定低延迟工作负载,例如 VOIP 工作负载或高频交易工作负载,则 SNC 是有意义的。

对于运行 Oracle、SQL 或任何需要大量 vCPU 的高性能数据库以及一些前端应用程序和大量其他框架的普通 vSphere 环境,SNC 将影响您的性能。大多数管理员都希望 VM 适合单个 NUMA 节点。SNC 可减少虚拟机占用空间。SNC 会更严重地限制内存访问。由于本地和远程 I/O 之间的差距增加,用户将检测到工作负载性能感觉更加不一致。NUMA 调度程序现在需要平衡四个较小的 NUMA 域,而不是两个较大的域。因此,将做出更多可能不是最佳的决策。以短期迁移为例。NUMA 计划程序移动 VM 以解决 NUMA 节点之间的不平衡问题。在这种情况下,调度程序会立即迁移 vCPU,但内存的迁移速度会变慢。由于内存重定位不是即时的,因此当页面迁移到新的 NUMA 节点时,远程内存访问将暂时增加。由于需要处理四个较小的 NUMA 节点,这可能会影响整体用户体验,尤其是在本地和远程内存之间的差距从 69% 扩大到 90% 的情况下。

可能是统一内存访问 VM(适合单个 NUMA 节点)的 VM 现在跨多个 NUMA 节点。因此,我们希望来宾操作系统和应用程序得到 NUMA 优化。最近对他们的 NUMA 调度程序的 Linux 优化让我 充满希望,但 将主机保持为默认 NUMA 可以避免如此多的性能不一致。

从本质上讲,我认为SNC适用于高度优化,精心策划的环境,该环境利用了本书中的每一个技巧。它不应该是每个虚拟化平台的起点。

继续滑动看下一个
向上滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存