3.4 软中断CPU开销与亲和性

软中断开销估算

通过 top 命令可以查看每个CPU上软中断的开销占比(si 列)。例如:

Cpu(s):  7.1%us,  1.4%sy,  0.0%ni, 90.1%id,  0.1%wa,  0.2%hi,  1.2%si,  0.0%st

CPU 约花费 1.2% 的时钟周期在软中断上,即每个核约 12ms。

通过 vmstat 1 查看软中断次数(in 列):

procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 2  0      0 1231352 339244 55474204    0    0     0   128 57402 24593  5  2 92  0  0

每秒约 56000 次软中断(该机器为网络IO密集型服务)。

假设机器为 16 核物理机,则每个软中断所需的 CPU 时间 ≈ 12ms / (56000/16)3.428 μs

软中断开销包含两部分

  • 上下文切换开销:从用户进程切换到内核线程 ksoftirqd,类似于系统调用但更轻量。
  • 内核执行开销:网络协议栈处理等。

对比:

通过 /proc/interrupts 查看中断号

每个可中断设备都有一个中断号,可通过以下文件查看:

cat /proc/interrupts

示例输出(虚拟机):

           CPU0       CPU1       CPU2       CPU3
27:        351          0          0  280559832   PCI-MSI-edge      virtio1-input.0
28:          1          0          0          0   PCI-MSI-edge      virtio1-output.0
30:    4233459  375136079     244872     474097   PCI-MSI-edge      virtio2-input.0
31:          1          0          0          0   PCI-MSI-edge      virtio2-output.0
  • virtio1-input.0virtio1-output.0 对应虚拟网卡 eth0 的收发队列,中断号分别为 2728
  • virtio2-input.0virtio2-output.0 对应虚拟网卡 eth1 的收发队列,中断号分别为 3031

每个中断号的CPU亲和性可通过 /proc/irq/<IRQ>/smp_affinity 查看(掩码形式,十六进制):

cat /proc/irq/30/smp_affinity

输出 2 表示绑定到 CPU1(位掩码从 CPU0 开始,第1位为1)。

irqbalance 与 CPU 亲和性设置

系统默认由 irqbalance 服务自动维护中断的CPU亲和性,以均衡各核的中断负载。查看服务:

ps -ef | grep irqb

输出示例:

root 29805     1  0 18:57 ?        00:00:00 /usr/sbin/irqbalance --foreground

若需手动调整,先关闭 irqbalance

service irqbalance stop

然后直接写入新的亲和性掩码:

echo 2 > /proc/irq/30/smp_affinity   # 将30号中断绑定到CPU1

WARNING

手动修改后中断不再自动均衡,可能导致单核过载。另外,尝试将亲和性绑定到多个CPU(例如 echo 3)在某些环境下可能无效,依然只有一个核心处理软中断。

物理机上,网卡通常支持多队列,每个收发队列可以单独绑定不同的CPU,从而实现软中断的并行处理。


相关章节9.2 软中断CPU开销分析9.3软中断的亲和性系统调用进程上下文切换