查看中断分配
1 | cat /proc/interrupts |
典型输出如下:
1 | CPU0 CPU1 CPU2 CPU3 |
其中 serial-tegra.1 对应 TK1 上 /dev/ttyTHS1 的中断。第一列代表的是中断号,每个 CPU 下面的数字代表接收到的中断数。
默认情况下,系统用 CPU0 去收所有的中断。处理中断是非常耗时的任务,而系统又认为所有 CPU 的计算能力是一致的。当 CPU0 用了 30% 的资源去处理中断时,那别的 CPU 也只能发挥 70% 的计算性能,所以需要合理分配中断。
SMP/Processor affinity
Affinity 指的是任务与处理器的亲和度。如果我们一直用处理器 X 运行任务 Y,两者 affine。Affine 的情况下,处理器的 cache 里会存有任务部分的 memory,所以效率是比较高的。
和一般进程相反,对中断来说,affine 到某个处理器则会导致低效。因为中断程序往往非常小,将中断程序存在 CPU 里不能改善 cache hits,而多个中断会长期占用 CPU。调度器会认为所有核都和这个中断处理核一样忙,导致其它 CPU 实际上很空闲,但是缺用不上。
APIC (Advanced Programmable Interrupt Controller)
APIC 负责分配中断,默认将所有中断交给 CPU0 处理。APIC 具有好几种传输 (delivery) 及 (destination) 模式,包括:
- physical
- logical
- fixed
- low priority
能够将中断绑到任意核上 (其实只能绑到前八个核),还能做负载均衡。
使用
- 对某些系统来说,可能需要先停掉 irqbalance 服务
1 | # /etc/init.d/irqbalance stop |
对每一个中断号, /proc/irq/ 下面都有一个对应的目录,下面有一个 smp_affinity 文件,通过修改这个文件,能够改变该中断绑定的核。
文件里存的是一个 16 进制的 bitmask。哪一位为 1,就用哪个核。
比如说我们要让 CPU1 处理 TK1 的串口中断,可以这样:
1 | sudo bash -c 'echo 2 > /proc/irq/69/smp_affinity' |
理论上,f 能够使四个核平均处理中断。但是,实际结果还要看 APIC 是否处于 physical destination mode 及 low priority delivery mode,如果是的话才可以,可惜 TK1 不是。
- 在内核里关掉 CONFIG_HOTPLUG_CPU 可以使 APIC 正常工作
ubuntu 可以安装一个叫 irqbalance 的东西,说不定可以解决