硬中断亲缘性调优:网卡多队列与CPU绑定实战 - 第3节

3.1 对称多处理架构(SMP)

对称多处理(Symmetric Multi-Processing,SMP)是现代服务器与桌面系统中最核心的硬件架构之一。在 SMP 系统中,所有 CPU 核心共享同一块物理内存与 I/O 总线,每个核心在操作系统看来是对等的——任何中断、进程或线程都可以被调度到任意核心上执行。

这种“对称性”带来了极大的灵活性,但也引入了缓存一致性与中断分布两大挑战。理解 SMP 的内部结构,是掌握中断亲缘性调优的前提。

SMP 核心特征:
  • 所有 CPU 核心共享统一地址空间(UMA,Uniform Memory Access)。
  • 每个核心拥有独立的 L1/L2 缓存,通过缓存一致性协议(如 MESI)保持同步。
  • 中断控制器(如 APIC、I/O APIC)可将外部中断路由到任意核心。
  • 操作系统调度器(如 Linux CFS)在核心间均衡分配负载。
对称多处理(SMP)架构示意图 CPU Core 0 L1/L2 缓存 CPU Core 1 L1/L2 缓存 CPU Core 2 L1/L2 缓存 CPU Core 3 L1/L2 缓存 缓存一致性总线(MESI 协议) 共享 L3 缓存 内存控制器(IMC) 系统内存(DRAM)

3.2 中断亲缘性概念

中断亲缘性(Interrupt Affinity)是指将特定硬件中断的响应处理绑定到指定的 CPU 核心或核心集合上。在 SMP 系统中,默认情况下中断可能被分配到任意核心,这会导致缓存抖动、跨 NUMA 访问延迟以及锁竞争加剧。

通过设置中断亲缘性,可以实现以下目标:

  • 缓存局部性:中断处理程序及其对应的数据流始终在同一核心上执行,L1/L2 缓存命中率显著提升。
  • 负载隔离:将高频率中断(如网卡 RX/TX)绑定到专用核心,避免干扰关键业务进程。
  • NUMA 感知:确保中断处理核心与设备所在 NUMA 节点一致,消除跨节点内存访问延迟。
性能观察:在 40Gbps 网卡场景下,未设置中断亲缘性时,跨 NUMA 中断处理可导致吞吐量下降 15%–25%,同时增加 30%–50% 的缓存未命中率。绑定到同一 NUMA 节点后,延迟抖动明显收敛。

3.3 CPU 亲和性掩码

CPU 亲和性掩码(Affinity Mask)是 Linux 内核用于描述 CPU 核心集合的位图数据结构。每个位代表一个逻辑 CPU 核心,位值为 1 表示该核心被允许处理中断或运行进程。

3.3.1 掩码格式与表示

表示方式 示例 说明
十六进制 0x0f CPU 0–3 被选中(位 0–3 为 1)
二进制 00001111 与十六进制等价,低位对应 CPU 0
十进制 15 0x0f 的十进制值
列表形式 0-3 工具(如 taskset)支持的简写

3.3.2 掩码与中断重映射

在 x86 系统中,中断亲缘性通过 I/O APIC 和 MSI/MSI-X 机制实现。每个中断向量对应一个 /proc/irq/<IRQ>/smp_affinity 文件,写入掩码即可改变路由目标。

关键文件路径:
  • /proc/irq/<IRQ>/smp_affinity — 十六进制掩码,直接控制中断路由。
  • /proc/irq/<IRQ>/smp_affinity_list — 列表形式(如 0-3),便于脚本处理。
  • /proc/irq/<IRQ>/effective_affinity — 内核实际生效的掩码(考虑 cpuset 约束)。
中断亲缘性路由流程 网卡(NIC) IRQ 请求 I/O APIC 读取 smp_affinity CPU 0(掩码位 0) CPU 1(掩码位 1)

3.4 实战:查看与修改中断亲缘性

以下操作基于 Linux 内核 4.18+,使用 irqbalance 服务可能覆盖手动设置,建议先关闭或配置白名单。

3.4.1 查看当前中断分配

# 查看所有中断的 CPU 分布
cat /proc/interrupts | grep eth0

# 查看特定 IRQ 的亲缘性掩码
cat /proc/irq/78/smp_affinity
# 输出示例:00000000,00000000,00000000,0000000f

# 查看实际生效核心
cat /proc/irq/78/effective_affinity
# 输出示例:0-3

3.4.2 修改中断亲缘性

# 将 IRQ 78 绑定到 CPU 0-1(掩码 0x03)
echo 03 > /proc/irq/78/smp_affinity

# 使用列表形式(需要内核支持)
echo 0-1 > /proc/irq/78/smp_affinity_list

# 验证修改
cat /proc/irq/78/smp_affinity
# 输出:00000000,00000000,00000000,00000003
注意事项:
  • 修改 smp_affinity 需要 root 权限。
  • 对于 MSI-X 设备,每个队列有独立的 IRQ,需逐队列设置。
  • 避免将中断绑定到 CPU 0(通常用于系统管理中断),除非明确测试过。
  • 在 NUMA 系统中,优先绑定到设备所在节点的 CPU 核心。

3.5 中断亲缘性与 NUMA 拓扑

在 NUMA(Non-Uniform Memory Access)架构中,中断亲缘性的重要性进一步放大。如果网卡中断被分配到非本地 NUMA 节点的 CPU,每次中断处理都需要跨 QPI/UPI 总线访问内存,延迟增加 30%–70%。

场景 本地节点处理 跨节点处理 性能差异
内存访问延迟 ~100 ns ~170 ns +70%
L3 缓存命中率 85%–95% 60%–75% 下降 20%
网卡吞吐量(40Gbps) 38 Gbps 31 Gbps -18%
NUMA 感知绑定策略:使用 lscpu 查看 NUMA 节点拓扑,然后通过 numactl --hardware 确认设备所在节点。对于 PCIe 设备,可通过 cat /sys/class/net/eth0/device/numa_node 获取其 NUMA 节点编号。

3.6 本章小结

  • SMP 架构提供了对称的 CPU 资源,但中断分配不当会引发缓存和总线竞争。
  • 中断亲缘性通过 smp_affinity 掩码控制中断路由目标,是实现性能隔离的核心手段。
  • CPU 亲和性掩码使用位图表示,支持十六进制、二进制、列表等多种格式。
  • NUMA 环境下,中断亲缘性必须与设备节点对齐,否则跨节点访问将严重拖累性能。