1. 多核CPU架构基础:SMP与NUMA架构的区别、CPU拓扑结构(socket/core/thread)、缓存层级(L1/L2/L3)对性能的影响
1.1 SMP 与 NUMA:两种核心架构模型
现代多核服务器主要采用两种内存访问架构:SMP(对称多处理) 与 NUMA(非统一内存访问)。理解二者的区别是进行 CPU 绑定与中断亲和性优化的前提。
| 特性 | SMP(对称多处理) | NUMA(非统一内存访问) |
|---|---|---|
| 内存访问方式 | 所有 CPU 通过共享总线访问同一块物理内存,访问延迟一致 | 每个 CPU 节点拥有本地内存,访问本地内存快,访问远端内存慢 |
| 扩展性 | 总线带宽成为瓶颈,通常适用于 2~8 核的小型系统 | 通过互联网络(如 QPI/UPI)连接节点,可扩展到数百核 |
| 延迟差异 | 无差异(Uniform Memory Access) | 本地 vs 远端延迟差异可达 1.5~3 倍 |
| 典型应用 | 桌面 CPU、低端嵌入式多核 | 服务器 CPU(Intel Xeon、AMD EPYC)、高性能计算 |
| 中断亲和性影响 | 中断可均衡分配到任意 CPU,效果相近 | 中断必须优先绑定到本地 CPU 节点,否则性能下降明显 |
优化启示: 在 NUMA 架构下,CPU 绑定 和 中断亲和性 必须考虑“本地性”原则——让进程和中断尽量在同一个 NUMA 节点内运行,避免跨节点内存访问带来的延迟惩罚。
1.2 CPU 拓扑结构:Socket / Core / Thread
Linux 内核通过 /sys/devices/system/cpu/ 和 lscpu 命令暴露 CPU 拓扑信息。理解 Socket(物理插槽)→ Core(物理核心)→ Thread(逻辑处理器/超线程) 的层级关系,是配置亲和性的基础。
关键指标:
- Socket 数量:决定了 NUMA 节点数量(通常 1 Socket = 1 NUMA 节点)。
- Core per Socket:每个物理插槽上的物理核心数。
- Thread per Core:超线程技术,通常为 2(即每个物理核心对应 2 个逻辑 CPU)。
- 总逻辑 CPU 数 = Socket × Core per Socket × Thread per Core。
1.3 缓存层级:L1 / L2 / L3 对性能的影响
缓存是 CPU 与内存之间的高速缓冲层,其层级结构直接影响数据访问延迟和带宽。在 CPU 绑定优化中,缓存亲和性(Cache Affinity) 是核心考量因素。
| 缓存层级 | 典型大小 | 访问延迟 | 所属关系 | 优化影响 |
|---|---|---|---|---|
| L1 缓存 | 32KB ~ 64KB(指令+数据分离) | ~1ns(4~5 个 CPU 周期) | 每个 Thread 私有 | 线程频繁切换导致 L1 失效,性能下降 |
| L2 缓存 | 256KB ~ 1MB | ~3ns(10~12 个 CPU 周期) | 每个 Core 私有(同一 Core 的 Thread 共享) | 超线程共享 L2,避免资源争抢 |
| L3 缓存 | 8MB ~ 64MB(甚至更大) | ~10ns(30~40 个 CPU 周期) | 同一 Socket 内所有 Core 共享 | 跨 Socket 访问 L3 需通过 QPI/UPI,延迟增加 |
性能陷阱: 在 NUMA 系统中,如果进程或中断被调度到 非本地 Socket 的 Core 上,即使 L3 缓存命中,也需要通过互联总线访问远端内存,延迟可能从 ~10ns 飙升到 ~30ns 以上。这是 CPU 绑定优化必须解决的核心问题。
1.4 缓存层级与数据流示意图
以下 SVG 展示了数据从内存到 CPU 核心的完整路径,以及各级缓存在其中的作用:
1.5 性能影响总结:为什么 CPU 绑定如此重要
- 缓存命中率:将进程/中断绑定到固定 Core,可以最大化 L1/L2 缓存命中率,避免因跨 Core 迁移导致的缓存失效(Cache Miss)。
- NUMA 本地性:在 NUMA 系统中,绑定到本地 Socket 的 Core 可以避免跨节点内存访问,降低延迟 30%~50%。
- 中断亲和性:将网卡/存储中断绑定到特定 Core,可以避免中断在所有 Core 上“漂移”,减少上下文切换和缓存污染。
- 超线程感知:同一 Core 的两个 Thread 共享 L1/L2 缓存,绑定时应避免将两个高负载任务分配到同一 Core 的 Thread 上。
实践检查清单:
- 使用
lscpu查看 CPU 拓扑:lscpu --all --extended - 查看 NUMA 节点信息:
numactl --hardware - 查看每个 Core 的缓存大小:
lscpu --cache - 查看当前中断亲和性设置:
cat /proc/irq/*/smp_affinity