单进程、异步的I/O应该可以获得最优的通讯性能,但在现实中,我们常常发现这种模式达不到预期的效果,这可能是由于网卡在和应用程序争夺CPU资源。硬件中断的频繁发生是一件很消耗CPU资源的事情,在多CPU、多核心的条件下,如果有办法把大量硬件中断分配给特定的CPU核心进行处理,就能获得更好的性能。现在的服务器基本都是多CPU、多核心、多网卡、多硬盘,如果能分散和平衡各个中断,绑定特定的硬件中断到特定的CPU核心上,例如让网卡中断独占1个CPU 内核,磁盘I/O中断独占1个CPU核心,那么将会大大减轻单一CPU的负担,提高整体的处理效率。
1、什么是中断?
中文教材上对“中断”的定义太生硬了,简单的说就是:每个硬件设备(如硬盘、网卡等)都需要和CPU进行某种形式的通信,以便CPU及时知道发生了什么事情,这样CPU可能就会放下手中的事情去处理应急事件,硬件设备主动打扰CPU的现象就可以称为硬件中断。就像你正在工作的时候受到QQ干扰一样,一次QQ头像闪动就可以被理解为中断。
中断是一种比较好的CPU和硬件沟通的方式,还有一种方式叫做轮询(Polling),就是让CPU定时地对硬件状态进行查询然后做相应处理,就好像你每隔5分钟去检查一下QQ,看看有没有人找你一样,这种方式是不是很浪费时间呢?所以中断是硬件主动的方式,比轮询(CPU主动)更有效。这里又有了一个问题,每个硬件设备都中断,那么如何区分不同硬件呢?不同设备同时中断如何知道哪个中断是来自硬盘,哪个来自网卡呢?这个其实很容易,就好像每个QQ的号码都不相同,同样的,系统会为每个硬件设备分配一个IRQ号,通过这个唯一的IRQ号就能区别不同的硬件了。
在计算机里,美国服务器,中断是一种电信号,由硬件产生,并直接送到中断控制器上,然后再由中断控制器向CPU发送信号,CPU检测到该信号后,就中断当前的工作转而去处理中断。然后,处理器会通知操作系统已经产生中断,这样操作系统就会对这个中断进行适当的处理。现在来看一下中断控制器,常见的中断控制器有两种:可编程中断控制器8259A和高级可编程中断控制器(APIC)。传统的8259A只适合单CPU的情况,现在都是多CPU、多核心的SMP体系,所以为了充分利用SMP体系结构,把中断传递给系统上的每个CPU以便更好实现并行和提高性能,香港服务器,Intel引入了高级可编程中断控制器(APIC)。
光有高级可编程中断控制器的硬件支持还不够,Linux内核还必须能利用这些硬件的特质,所以只有kernel 2.4以后的版本才支持把不同的硬件中断请求(IRQs)分配到特定的CPU核心上,这个绑定技术被称为SMP IRQ Affinity。更多介绍请参看Linux内核源代码自带的文档:linux-2.6.31.8/Documentation/IRQ-affinity.txt。
2、如何使用?
我们首先来了解两个基本命令:
cat /proc/interrupts,查看系统上的中断情况,通常网卡的中断会被分配到CPU0上。cat cat /proc/cpuinfo,查看CPU信息,有多少CPU,有多少核心。
然后我们使用命令来查看系统上的中断是如何分配到CPU上的,网站空间,很显然CPU0上处理的中断多一些:
# cat /proc/interrupts
CPU0CPU1
0:
1:
8:
9:
12:
14:
50:
58:
90:
233:
NMI:
LOC:
ERR:
MIS:
918926335
2
0
0
4
8248017
194
31673
1070374
10
5077
918809969
0
0
0
0
0
0
0
0
0
0
0
0
2032
918809894
0
0
IO-APIC-edge
IO-APIC-edge
IO-APIC-edge
IO-APIC-level
IO-APIC-edge
IO-APIC-edge
IO-APIC-level
IO-APIC-level
PCI-MSI
IO-APIC-level
timer
i8042
rtc
acpi
i8042
ide0
ohci_hcd:usb2
sata_nv
eth0
ehci_hcd:usb1
世上没有绝望的处境,只有对处境绝望的人。