本文将mark下Intel Sub-NUMA Clustering(SNC)的相关notes。

What

Sub-NUMA Clustering(SNC) 是 Intel Xeon 处理器提供的一种 NUMA 拓扑配置技术。

它把一个物理 CPU Socket 内部的资源进一步划分成若干个”局部访问域”,每个域通常包含:

  • 一部分 CPU Core;
  • 一部分 LLC Slice 和 CHA(Caching/Home Agent);
  • 一部分集成内存控制器 IMC;
  • 由这些内存控制器连接的本地 DRAM。

随后,BIOS 将每个局部域作为一个独立的 NUMA Node 暴露给操作系统。这样,操作系统和应用程序就可以把线程及其内存放在同一个 SNC 域中,从而减少 CPU 芯片内部的远距离数据访问。

Motivation

假设一个 Socket 内有两组 Core 和两个内存控制器:

1
2
3
4
5
6
7
8
9
10
11
Socket 0

Core 组 A ───── IMC 0 ───── DRAM A



└──────── 片内互连 ────────┐



Core 组 B ───── IMC 1 ───── DRAM B

对于 Core 组 A 来说:

1
2
3
访问 IMC 0 / DRAM A:距离较近

访问 IMC 1 / DRAM B:距离较远

但是,如果 SNC 关闭,操作系统通常只看到:

1
Socket 0 = NUMA Node 0

操作系统会认为 Socket 0 内的所有 Core 和所有内存都是同一个 NUMA 域,无法明确区分:

1
2
3
这块内存靠近 Core 组 A

还是靠近 Core 组 B

于是可能出现:

1
2
3
4
5
6
7
8
9
10
11
12
13
线程运行在 Core 组 A





访问芯片另一侧的 LLC / IMC 1





DRAM B

这种访问仍然可以正常完成,但需要经过更长的片内路径,可能带来:

  • 更高的 LLC 访问延迟;
  • 更高的内存访问延迟;
  • 更多片内互连流量;
  • 内存控制器或互连局部拥塞;
  • 多核扩展性下降。

Why

Intel 引入 Sub-NUMA Clustering(SNC),是因为现代 Xeon 的单个 Socket 已经非常大:

  • Core 数量越来越多;
  • LLC 被分散成很多 Slice;
  • 多个内存控制器 IMC 分布在芯片不同位置;
  • Core、LLC、CHA、IMC 之间通过片内互连连接。

因此,虽然这些资源都属于同一个 Socket,但一个 Core 访问”附近”的 LLC/内存控制器,与访问芯片另一侧的 LLC/内存控制器,实际路径和延迟并不相同。

SNC 的目的,就是把这种 Socket 内部原本隐藏的距离差异暴露给操作系统,让线程尽量使用附近的缓存和内存。 Intel 也明确指出:当整个 Socket 作为一个统一域时,软件无法根据最近资源优化数据流,一个 Core 可能访问位于芯片另一侧的 LLC Slice 或内存控制器。

1
2
3
4
5
6
7
8
9
10
11
12
现代 Xeon Socket 很大

Socket 内部访问已经不是完全等距离

但操作系统若只看到一个 NUMA Node,
就无法区分近端和远端资源

SNC 将一个 Socket 划分为多个局部 NUMA 域

让线程尽量访问本地 LLC、IMC 和 DRAM

降低延迟、减少片内流量、改善内存带宽利用率

How

SNC 把一个大 Socket 划分成多个较小的”局部访问域”。

以 SNC2 为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
                     Socket 0

┌──────────────────────┬──────────────────────┐

│ SNC Domain 0 │ SNC Domain 1 │

│ OS NUMA Node 0 │ OS NUMA Node 1 │

│ │ │

│ Core 组 A │ Core 组 B │

│ 本地 LLC / CHA │ 本地 LLC / CHA │

│ IMC 0 │ IMC 1 │

│ DRAM A │ DRAM B │

└──────────────────────┴──────────────────────┘

操作系统现在能看到两个 NUMA Node,于是可以进行更精确的放置:

1
2
3
4
5
6
7
8
9
线程运行在 Node 0 的 Core

+

内存分配在 Node 0 的 DRAM



Core → 本地 LLC/CHA → 本地 IMC → 本地 DRAM

Intel 对 SNC2 的描述也是:每个局部域包含相关的 Core、本地 LLC Slice 和本地内存控制器;本地域内的 Core 访问本域映射的数据时,可以获得更低的 LLC 和内存延迟。

本质:让软件看见 Socket 内部的局部性

可以把 SNC 的价值概括为一句话:

SNC 把”Socket 内部事实上存在、但操作系统原本看不见的 NUMA 差异”,变成操作系统可见的 NUMA Node。

SNC 关闭

1
2
3
4
5
6
7
8
9
物理上:

Core A 靠近 IMC 0

Core B 靠近 IMC 1

但操作系统看到:

所有 Core + 所有内存 = 一个 NUMA Node

SNC 开启

1
2
3
4
5
6
7
8
9
10
11
物理上:

Core A + LLC/CHA A + IMC 0 + DRAM A

Core B + LLC/CHA B + IMC 1 + DRAM B

操作系统看到:

NUMA Node 0

NUMA Node 1

这样,操作系统和应用就可以通过 NUMA 策略安排:

  • 线程运行在哪组 Core;
  • 内存由哪个 IMC 分配;
  • 数据放在哪个 SNC 域;
  • 不同进程或数据分片分别使用哪些资源。

所以 SNC 并不是简单地”把 CPU 切成几份”,而是为了建立:

1
2
3
4
5
6
7
8
9
10
11
12
13
Core



附近的 LLC / CHA



附近的 IMC



本地 DRAM

这种更明确的局部关系。

收益

降低本地访问延迟

理想情况下:

1
2
3
SNC 关闭:

Core → 较远 LLC/CHA → 较远 IMC → DRAM

变成:

1
2
3
SNC 开启且放置正确:

Core → 本地 LLC/CHA → 本地 IMC → 本地 DRAM

Intel 将降低芯片内数据移动延迟作为 SNC 的直接设计目的。

减少片内互连流量

如果线程不断访问其他区域的 LLC Slice 和 IMC,数据会在片内互连上来回传输。

SNC 将大部分访问限制在局部域内,可以减少:

1
跨 SNC 域的数据移动

从而降低互连竞争。

更好地利用多个内存控制器

例如 SNC2 中:

1
2
3
业务实例 A → Node 0 → IMC 0

业务实例 B → Node 1 → IMC 1

两个实例分别使用不同的局部资源,有助于避免所有线程集中访问同一组内存控制器。

因此,SNC 通常并不是提高 DRAM 的理论带宽,而是让应用程序更充分、更均衡地利用已有内存带宽。

提高大规模多核程序的扩展性

当 Core 数量很多时,如果所有线程都被视为处在一个统一域中,线程和内存可能随机分散。

SNC 允许程序按域划分工作:

1
2
3
4
5
6
7
SNC Domain 0 → 数据分片 0

SNC Domain 1 → 数据分片 1

SNC Domain 2 → 数据分片 2

SNC Domain 3 → 数据分片 3

这特别适合:

  • MPI / MPI+OpenMP 程序;
  • NUMA-aware 数据库;
  • 分片式缓存或存储服务;
  • 多实例虚拟化;
  • 每个 Worker 有独立工作集的程序。

总结

Intel SNC 的核心思想可以概括为:

把一个很大的 CPU Socket 拆成多个较小的局部 NUMA 域,让 Core 尽量访问附近的 LLC、内存控制器和 DRAM。


参考资料:

  1. Intel Xeon Processor Scalable Family Technical Overview:Sub-NUMA Clustering
  2. Intel Xeon Scalable Processor Max Series:SNC2 与 SNC4
  3. Intel Xeon 6 BIOS NUMA Tuning Guide
  4. Linux Kernel Documentation:Notes on Sub-NUMA Cluster Mode
  5. Intel HPC Cluster Tuning Guide:SNC 与 NUMA 工具
  6. Intel White Paper:Qdrant/VectorDB 工作负载下 SNC 开关的性能影响