跳转至

numa

NUMA(Non-Uniform Memory Access,非统一内存访问)是一种计算机内存架构,广泛应用于多处理器系统(如服务器和高性能计算系统),用于提高系统性能。


NUMA 的基本概念

在 NUMA 架构中,每个 CPU(或 CPU 核心)都有直接连接的本地内存(local memory)。

  • 本地内存访问:CPU 访问自己本地内存时,延迟低,性能高。
  • 远程内存访问:CPU 需要通过其他 CPU 的互连(Interconnect)访问远程内存,延迟较高,性能较低。

与传统的 UMA(Uniform Memory Access,统一内存访问) 相比,NUMA 的特点是内存访问的延迟和带宽不统一,依赖于内存的物理位置。


NUMA 的核心组成

  1. NUMA 节点(Node)
  2. 每个节点包含一组 CPU 和直接连接的内存。
  3. CPU 在其节点的内存访问速度更快,访问其他节点的内存速度较慢。
  4. CPU 间互连(Interconnect)
  5. 用于连接不同 NUMA 节点,允许跨节点共享内存。
  6. 常见技术:Intel QPI、AMD Infinity Fabric。
  7. 本地与远程内存
  8. 本地内存:CPU 节点直接连接的内存。
  9. 远程内存:通过互连访问的其他节点的内存。

NUMA 的优点

  1. 提高内存访问性能
  2. 通过尽量使用本地内存,减少访问远程内存的频率,优化延迟。
  3. 扩展性强
  4. 系统可以增加更多的 NUMA 节点,而不会因共享总线的瓶颈而显著降低性能。

NUMA 的挑战

  1. 远程访问开销高
  2. 远程内存访问的延迟和带宽会显著影响性能。
  3. 需要软件优化
  4. 操作系统、数据库、虚拟机等需要针对 NUMA 架构进行优化(如合理的任务调度和内存分配)。
  5. 复杂性
  6. 开发者需要考虑内存和任务的绑定策略。

NUMA 的典型应用

  1. 服务器和数据中心
  2. 例如数据库(如 MySQL、PostgreSQL)、虚拟化平台(如 VMware、KVM)。
  3. 高性能计算(HPC)
  4. 科学计算和工程仿真等任务需要高效的内存使用。
  5. 多核 CPU 环境
  6. 提高多线程程序的内存访问效率。

与 NUMA 相关的工具

  1. numactl
  2. 控制进程运行在哪个 NUMA 节点,指定内存分配策略。
  3. numastat
  4. 查看 NUMA 节点的内存使用情况。
  5. Linux 内核的 NUMA 支持
  6. 如自动内存分配优化(Transparent Huge Pages 和 AutoNUMA)。

NUMA 系统示例

假设一个 NUMA 系统有两个节点:

  • 节点 0:CPU 0-31,内存 128 GB。
  • 节点 1:CPU 32-63,内存 128 GB。

CPU 0 访问节点 0 的内存延迟为 10,访问节点 1 的内存延迟为 20。合理分配任务和内存可以极大提升性能,比如将需要大量内存的任务绑定到节点 0 的 CPU 和内存。


[root@ ~]# numactl --hardware
available: 2 nodes (0-1) # 系统中有 2 个 NUMA 节点,编号分别为 0 和 1

node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 # NUMA 节点 0 包含 CPU 核心编号为 0 到 31 的处理器核心

node 0 size: 388457 MB # NUMA 节点 0 的总物理内存大小为 388457 MB(约 379 GB)

node 0 free: 178917 MB # NUMA 节点 0 当前未分配的内存大小为 178917 MB(约 174 GB)

node 1 cpus: 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 # NUMA 节点 1 包含 CPU 核心编号为 32 到 63 的处理器核心

node 1 size: 389212 MB # NUMA 节点 1 的总物理内存大小为 389212 MB(约 380 GB)

node 1 free: 178121 MB # NUMA 节点 1 当前未分配的内存大小为 178121 MB(约 173 GB)

node distances: # 显示不同 NUMA 节点之间的内存访问延迟
node   0   1 # 表示节点编号
  0:  10  15 # 节点 0 访问自身内存的延迟为 10,访问节点 1 内存的延迟为 15
  1:  15  10 # 节点 1 访问节点 0 内存的延迟为 15,访问自身内存的延迟为 10

numactl

numactl 是一个用于管理和优化 NUMA(非统一内存访问架构)系统性能的工具。NUMA 是一种内存架构,在这种架构中,每个 CPU 都有自己直接连接的本地内存,同时也可以访问其他 CPU 的内存(称为远程内存),但远程内存的访问延迟通常比本地内存高。

numactl 的主要功能:

  1. 绑定进程到特定的 CPU 或内存节点

  2. 可以将进程或线程绑定到特定的 NUMA 节点上的 CPU 或内存,以减少远程内存访问的开销,从而提升性能。

  3. 示例:

    numactl --cpunodebind=0 --membind=0 myprogram

    上述命令将 myprogram 绑定到 NUMA 节点 0 的 CPU 和内存上。

  4. 指定内存分配策略

  5. 控制进程如何分配内存,例如优先使用本地内存、跨节点分配内存等。

  6. 常见策略:

    • --membind: 将内存分配绑定到特定 NUMA 节点。
    • --interleave: 让内存分配在多个节点之间交错分布,适合需要均匀分布内存负载的场景。
    • --localalloc: 优先分配本地内存。
  7. 示例:

    numactl --interleave=all myprogram

    上述命令将 myprogram 的内存分配在所有 NUMA 节点之间交错分布。

  8. 查询 NUMA 系统信息

  9. 使用 numactl --hardware 可以查看当前系统的 NUMA 拓扑信息,包括节点数、每个节点的内存大小和 CPU 分布等。

  10. 示例:

    numactl --hardware
  11. 提高性能

  12. 在多核、多内存节点的系统中,合理使用 numactl 可以显著降低内存访问延迟,提高应用的吞吐量和性能。

常用选项:

  • --cpunodebind=<nodes>: 绑定进程到指定的 CPU 节点。
  • --membind=<nodes>: 将进程的内存绑定到指定的 NUMA 节点。
  • --interleave=<nodes>: 在指定节点间交错分配内存。
  • --localalloc: 仅分配本地内存。

使用场景:

  • 高性能计算:减少跨 NUMA 节点的内存访问,优化计算密集型任务的性能。
  • 数据库应用:绑定数据库实例到特定节点,降低内存和 CPU 的争用。
  • 容器部署:在多 NUMA 节点的机器上合理分配资源,提高容器性能。

如果你的应用对延迟敏感或运行在多 NUMA 节点的服务器上,了解和使用 numactl 是非常有价值的。