2. GPU架构基础:SM/CU单元、内存层次结构、PCIe拓扑与NUMA节点

GPU亲和性调优的核心在于理解GPU的物理架构与系统互连拓扑。本章从计算单元、内存层次、PCIe拓扑和NUMA节点四个维度,建立性能调优所需的硬件认知基础。

2.1 SM与CU:GPU的计算核心

NVIDIA GPU的基本计算单元是流多处理器(Streaming Multiprocessor, SM),每个SM内部包含多个CUDA核心(CUDA Core, CU)。SM负责指令调度与执行,CU负责浮点/整数运算。

架构代际 SM内部CU数量 关键特性
Volta (V100) 64 CU + 8 Tensor Core 独立线程调度、混合精度
Turing (T4) 64 CU + 8 Tensor Core RT Core、整数并发
Ampere (A100) 64 CU + 4 Tensor Core 第三代Tensor Core、MIG
Hopper (H100) 128 CU + 4 Tensor Core DPX指令、Transformer引擎
调优要点:SM的占用率(Occupancy)直接影响指令发射效率。每个SM能同时驻留的最大线程块数量(通常为32-64块)和线程数量(通常1024-2048线程)决定了隐藏访存延迟的能力。调优目标是在寄存器压力和线程并行度之间找到平衡。
GPU SM内部架构示意图 流多处理器 (SM) CUDA Core ×16 FP32/INT32 CUDA Core ×16 FP32/INT32 CUDA Core ×16 FP32/INT32 CUDA Core ×16 FP32/INT32 Tensor Core ×4 Warp Scheduler ×4 共享内存 (L1/Shared) 每个SM包含多个CUDA Core组、Tensor Core、Warp Scheduler和共享内存,通过片上互连协同工作

2.2 GPU内存层次结构

GPU内存层次从片内到片外,延迟和带宽差异巨大。理解各级存储的特性是编写高效kernel的前提。

内存类型 位置 典型容量 延迟 带宽 作用域
寄存器 SM内部 256 KB / SM ~1 cycle 极高 线程私有
共享内存 SM内部 48-164 KB / SM ~5 cycles ~10 TB/s 线程块共享
L1缓存 SM内部 与共享内存统一 ~10 cycles ~5 TB/s SM内
L2缓存 芯片级 40-60 MB ~200 cycles ~2 TB/s 全局
全局内存 HBM/GDDR 16-80 GB ~400-800 cycles ~2-3 TB/s 所有线程
关键指标:全局内存带宽是GPU性能的瓶颈之一。以A100为例,HBM2e带宽约2 TB/s,而SM内部共享内存带宽可达10 TB/s以上。将频繁访问的数据从全局内存搬移到共享内存,可显著降低访存延迟。

2.3 PCIe拓扑与GPU间通信

在多GPU系统中,PCIe拓扑决定了GPU之间、GPU与CPU之间的数据通路。常见的拓扑结构包括:

  • 直连拓扑:GPU通过PCIe Switch直接连接到CPU Root Complex,延迟较低。
  • NVLink拓扑:GPU之间通过NVLink高速互连,带宽可达PCIe的5-10倍。
  • 跨Socket拓扑:GPU连接到不同CPU Socket,跨Socket通信需经过QPI/UPI链路,延迟显著增加。
典型双路服务器GPU拓扑 CPU Socket 0 NUMA Node 0 内存通道: 8 CPU Socket 1 NUMA Node 1 内存通道: 8 UPI 20.8 GT/s PCIe Switch 0 PCIe Switch 1 GPU 0 PCIe 4.0×16 GPU 1 PCIe 4.0×16 GPU 2 PCIe 4.0×16 GPU 3 PCIe 4.0×16 NVLink 600 GB/s GPU 0/1 连接到 CPU 0 (NUMA Node 0),GPU 2/3 连接到 CPU 1 (NUMA Node 1),跨NUMA访问延迟增加30-50%

2.4 NUMA节点与GPU亲和性

在非统一内存访问(NUMA)架构中,CPU和GPU通过PCIe总线连接到不同的内存控制器。GPU亲和性调优的核心原则是:

  1. 就近绑定:将GPU绑定到与其直连的CPU Socket(NUMA Node),避免跨Socket内存访问。
  2. 内存亲和性:使用 numactl 或 cudaSetDevice() 确保GPU分配的内存位于本地NUMA节点。
  3. 线程绑定:将CPU线程绑定到与GPU同NUMA节点的物理核心上。
常见陷阱:在多GPU系统中,默认情况下CUDA可能将GPU内存分配在任意NUMA节点。使用 cudaMemAdvise() 设置内存访问策略,或通过 cudaSetDevice() 显式指定设备,可避免跨NUMA访问带来的性能损失(通常20-40%)。

2.5 亲和性检测工具

实际调优前,先使用以下工具检测当前系统的拓扑结构:

工具 功能 关键输出
nvidia-smi topo -m 显示GPU与CPU/NUMA的拓扑关系 GPU到CPU的PCIe路径、NUMA节点映射
lstopo 可视化硬件拓扑(含PCIe、NUMA、缓存) 树形拓扑图,显示所有设备连接
numactl --hardware 显示NUMA节点和CPU核心分布 节点编号、核心范围、内存大小
cuda-compat-check 验证CUDA设备与CPU的兼容性 设备列表、驱动版本、拓扑信息
实战命令:
# 查看GPU拓扑
nvidia-smi topo -m

# 输出示例(部分):
#        GPU0    GPU1    GPU2    GPU3    CPU Affinity    NUMA Affinity
# GPU0     X      NV2     NV1     SYS     0-31            0
# GPU1    NV2      X      SYS     NV1     0-31            0
# GPU2    NV1     SYS      X      NV2     32-63           1
# GPU3    SYS     NV1     NV2      X      32-63           1

# 绑定GPU0到NUMA Node 0
numactl --cpunodebind=0 --membind=0 python train.py

2.6 亲和性调优策略总结

基于上述架构理解,GPU亲和性调优可归纳为以下步骤:

  1. 拓扑分析:使用 nvidia-smi topo -m 和 lstopo 获取系统拓扑图。
  2. NUMA绑定:将进程/线程绑定到与GPU同NUMA节点的CPU核心上。
  3. 内存分配:使用 cudaSetDevice() 和 cudaMalloc() 在本地GPU分配内存。
  4. 数据迁移:利用NVLink或PCIe直连路径,避免跨Socket数据传输。
  5. 验证效果:使用 nvprof 或 Nsight Systems 分析数据传输延迟和内核执行时间。
性能收益:在双路服务器(2×CPU + 4×GPU)场景下,正确的NUMA亲和性配置可使端到端训练性能提升15-30%,跨GPU通信延迟降低40-60%。这是所有GPU调度优化的第一步,也是最容易获得收益的一步。