全部博文(306)
分类: LINUX
2015-09-06 16:01:02
Linux 2.4内核之后引入了将特定中断绑定到指定的CPU的技术,称为SMP IRQ affinity.
当一个硬件(如磁盘控制器或者以太网卡), 需要打断CPU的工作时, 它就触发一个中断. 该中断通知CPU发生了某些事情并且CPU应该放下当前的工作去处理这个事情. 为了防止多个设置发送相同的中断, Linux设计了一套中断请求系统, 使得计算机系统中的每个设备被分配了各自的中断号, 以确保它的中断请求的唯一性. 从2.4 内核开始, Linux改进了分配特定中断到指定的处理器(或处理器组)的功能. 这被称为SMP IRQ affinity, 它可以控制系统如何响应各种硬件事件. 允许你限制或者重新分配服务器的工作负载, 从而让服务器更有效的工作. 以网卡中断为例,在没有设置SMP IRQ affinity时, 所有网卡中断都关联到CPU0, 这导致了CPU0负载过高,而无法有效快速的处理网络数据包,导致了瓶颈。 通过SMP IRQ affinity, 把网卡多个中断分配到多个CPU上,可以分散CPU压力,提高数据处理速度。
1
|
echo $bitmask > /proc/irq/IRQ #/smp_affinity
|
1
|
echo f > /proc/irq/44/smp_affinity
|
1
|
echo $cpuindex1-$cpuindex2 > /proc/irq/IRQ #/smp_affinity_list
|
1
|
echo 0-3 > /proc/irq/44/smp_affinity_list
|
首先我们来看看smp_affinity文件的内容
1
2
|
root@ hostname : /home/igi # cat /proc/irq/76/smp_affinity
ffffff
|
这个bitmask表示了76号中断将被路由到哪个指定处理器. bit mask转换成二进制后,其中的每一位代表了一个CPU. smp_affinity文件中的数值以十六进制显示。为了操作该文件,在设置之前我们需要把CPU位掩码从二进制转换到十六进制。
上面例子中每一个”f”代表了4个CPU的集合,最靠右边的值是最低位的意思。 以4个CPU的系统为例:
二进制 十六进制 CPU 0 0001 1 CPU 1 0010 2 CPU 2 0100 4 CPU 3 1000 8
二进制 十六进制 CPU 0 0001 1 + CPU 2 0100 4 ----------------------- bitmask 0101 5
二进制 十六进制 CPU 0 0001 1 CPU 1 0010 2 CPU 2 0100 4 + CPU 3 1000 8 ----------------------- bitmask 1111 f
假如有一个4个CPU的系统, 我们能给一个IRQ分配15种不同的CPU组合(实际上有16种,但我们不能给任何中断分配中断亲和为”0”的值, 即使你这么做,系统也会忽略你的做法)
类别 | 测试客户端 | 测试服务端 |
---|---|---|
型号 | BladeCenter HS22 | BladeCenter HS22 |
CPU | Xeon E5640 | Xeon E5640 |
网卡 | Broadcom NetXtreme II BCM5709S Gigabit Ethernet | Broadcom NetXtreme II BCM5709S Gigabit Ethernet |
内核 | 2.6.38-2-686-bigmem | 2.6.38-2-686-bigmem |
内存 | 24GB | 24GB |
系统 | Debian 6.0.3 | Debian 6.0.3 |
驱动 | bnx2 | bnx2 |
/proc/irq/74/smp_affinity 00ffff /proc/irq/75/smp_affinity 00ffff /proc/irq/76/smp_affinity 00ffff /proc/irq/77/smp_affinity 00ffff /proc/irq/78/smp_affinity 00ffff /proc/irq/79/smp_affinity 00ffff /proc/irq/80/smp_affinity 00ffff /proc/irq/81/smp_affinity 00ffff /sys/class/net/eth0/queues/rx-0/rps_cpus 00000000 /sys/class/net/eth0/queues/rx-1/rps_cpus 00000000 /sys/class/net/eth0/queues/rx-2/rps_cpus 00000000 /sys/class/net/eth0/queues/rx-3/rps_cpus 00000000 /sys/class/net/eth0/queues/rx-4/rps_cpus 00000000 /sys/class/net/eth0/queues/rx-5/rps_cpus 00000000 /sys/class/net/eth0/queues/rx-6/rps_cpus 00000000 /sys/class/net/eth0/queues/rx-7/rps_cpus 00000000 /sys/class/net/eth0/queues/rx-0/rps_flow_cnt 0 /sys/class/net/eth0/queues/rx-1/rps_flow_cnt 0 /sys/class/net/eth0/queues/rx-2/rps_flow_cnt 0 /sys/class/net/eth0/queues/rx-3/rps_flow_cnt 0 /sys/class/net/eth0/queues/rx-4/rps_flow_cnt 0 /sys/class/net/eth0/queues/rx-5/rps_flow_cnt 0 /sys/class/net/eth0/queues/rx-6/rps_flow_cnt 0 /sys/class/net/eth0/queues/rx-7/rps_flow_cnt 0 /proc/sys/net/core/rps_sock_flow_entries 0
/proc/irq/74/smp_affinity 000001 /proc/irq/75/smp_affinity 000002 /proc/irq/76/smp_affinity 000004 /proc/irq/77/smp_affinity 000008 /proc/irq/78/smp_affinity 000010 /proc/irq/79/smp_affinity 000020 /proc/irq/80/smp_affinity 000040 /proc/irq/81/smp_affinity 000080 /sys/class/net/eth0/queues/rx-0/rps_cpus 00000000 /sys/class/net/eth0/queues/rx-1/rps_cpus 00000000 /sys/class/net/eth0/queues/rx-2/rps_cpus 00000000 /sys/class/net/eth0/queues/rx-3/rps_cpus 00000000 /sys/class/net/eth0/queues/rx-4/rps_cpus 00000000 /sys/class/net/eth0/queues/rx-5/rps_cpus 00000000 /sys/class/net/eth0/queues/rx-6/rps_cpus 00000000 /sys/class/net/eth0/queues/rx-7/rps_cpus 00000000 /sys/class/net/eth0/queues/rx-0/rps_flow_cnt 0 /sys/class/net/eth0/queues/rx-1/rps_flow_cnt 0 /sys/class/net/eth0/queues/rx-2/rps_flow_cnt 0 /sys/class/net/eth0/queues/rx-3/rps_flow_cnt 0 /sys/class/net/eth0/queues/rx-4/rps_flow_cnt 0 /sys/class/net/eth0/queues/rx-5/rps_flow_cnt 0 /sys/class/net/eth0/queues/rx-6/rps_flow_cnt 0 /sys/class/net/eth0/queues/rx-7/rps_flow_cnt 0 /proc/sys/net/core/rps_sock_flow_entries 0
/proc/irq/74/smp_affinity 00ffff /proc/irq/75/smp_affinity 00ffff /proc/irq/76/smp_affinity 00ffff /proc/irq/77/smp_affinity 00ffff /proc/irq/78/smp_affinity 00ffff /proc/irq/79/smp_affinity 00ffff /proc/irq/80/smp_affinity 00ffff /proc/irq/81/smp_affinity 00ffff /sys/class/net/eth0/queues/rx-0/rps_cpus 0000ffff /sys/class/net/eth0/queues/rx-1/rps_cpus 0000ffff /sys/class/net/eth0/queues/rx-2/rps_cpus 0000ffff /sys/class/net/eth0/queues/rx-3/rps_cpus 0000ffff /sys/class/net/eth0/queues/rx-4/rps_cpus 0000ffff /sys/class/net/eth0/queues/rx-5/rps_cpus 0000ffff /sys/class/net/eth0/queues/rx-6/rps_cpus 0000ffff /sys/class/net/eth0/queues/rx-7/rps_cpus 0000ffff /sys/class/net/eth0/queues/rx-0/rps_flow_cnt 4096 /sys/class/net/eth0/queues/rx-1/rps_flow_cnt 4096 /sys/class/net/eth0/queues/rx-2/rps_flow_cnt 4096 /sys/class/net/eth0/queues/rx-3/rps_flow_cnt 4096 /sys/class/net/eth0/queues/rx-4/rps_flow_cnt 4096 /sys/class/net/eth0/queues/rx-5/rps_flow_cnt 4096 /sys/class/net/eth0/queues/rx-6/rps_flow_cnt 4096 /sys/class/net/eth0/queues/rx-7/rps_flow_cnt 4096 /proc/sys/net/core/rps_sock_flow_entries 32768
/proc/irq/74/smp_affinity 000001 /proc/irq/75/smp_affinity 000002 /proc/irq/76/smp_affinity 000004 /proc/irq/77/smp_affinity 000008 /proc/irq/78/smp_affinity 000010 /proc/irq/79/smp_affinity 000020 /proc/irq/80/smp_affinity 000040 /proc/irq/81/smp_affinity 000080 /sys/class/net/eth0/queues/rx-0/rps_cpus 0000ffff /sys/class/net/eth0/queues/rx-1/rps_cpus 0000ffff /sys/class/net/eth0/queues/rx-2/rps_cpus 0000ffff /sys/class/net/eth0/queues/rx-3/rps_cpus 0000ffff /sys/class/net/eth0/queues/rx-4/rps_cpus 0000ffff /sys/class/net/eth0/queues/rx-5/rps_cpus 0000ffff /sys/class/net/eth0/queues/rx-6/rps_cpus 0000ffff /sys/class/net/eth0/queues/rx-7/rps_cpus 0000ffff /sys/class/net/eth0/queues/rx-0/rps_flow_cnt 4096 /sys/class/net/eth0/queues/rx-1/rps_flow_cnt 4096 /sys/class/net/eth0/queues/rx-2/rps_flow_cnt 4096 /sys/class/net/eth0/queues/rx-3/rps_flow_cnt 4096 /sys/class/net/eth0/queues/rx-4/rps_flow_cnt 4096 /sys/class/net/eth0/queues/rx-5/rps_flow_cnt 4096 /sys/class/net/eth0/queues/rx-6/rps_flow_cnt 4096 /sys/class/net/eth0/queues/rx-7/rps_flow_cnt 4096 /proc/sys/net/core/rps_sock_flow_entries 32768
测试方法: 每种测试类型执行3次,中间睡眠10秒, 每种测试类型分别执行100、500、1500个实例, 每实例测试时间长度为60秒
1
|
netperf -t TCP_RR -H $serverip -c -C -l 60
|
1
|
netperf -t UDP_RR -H $serverip -c -C -l 60
|
1
|
netperf -t TCP_RR -H $serverip -c -C -l 60 -- -r256,256
|
1
|
netperf -t UDP_RR -H $serverip -c -C -l 60 -- -r256,256
|
以小数据包1500进程测试的CPU(除了明确指明类型,否则这里的负载都是TCP_RR测试的负载)负载数据为示例
Average: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle Average: all 2.15 0.00 11.35 0.00 0.00 5.66 0.00 0.00 80.84 Average: 0 0.12 0.00 0.65 0.00 0.00 90.86 0.00 0.00 8.38 Average: 1 8.36 0.00 37.46 0.00 0.00 0.00 0.00 0.00 54.19 Average: 2 7.92 0.00 32.94 0.00 0.00 0.00 0.00 0.00 59.13 Average: 3 5.68 0.00 23.96 0.00 0.00 0.00 0.00 0.00 70.36 Average: 4 0.78 0.00 9.77 0.07 0.00 0.00 0.00 0.00 89.39 Average: 5 0.67 0.00 8.87 0.00 0.00 0.00 0.00 0.00 90.47 Average: 6 0.77 0.00 6.91 0.00 0.00 0.00 0.00 0.00 92.32 Average: 7 0.50 0.00 5.55 0.02 0.00 0.00 0.00 0.00 93.93 Average: 8 7.29 0.00 37.16 0.00 0.00 0.00 0.00 0.00 55.55 Average: 9 0.35 0.00 2.28 0.00 0.00 0.00 0.00 0.00 97.37 Average: 10 0.27 0.00 2.01 0.00 0.00 0.00 0.00 0.00 97.72 Average: 11 0.25 0.00 1.87 0.00 0.00 0.00 0.00 0.00 97.88 Average: 12 0.23 0.00 2.78 0.00 0.00 0.00 0.00 0.00 96.99 Average: 13 0.27 0.00 2.70 0.00 0.00 0.00 0.00 0.00 97.04 Average: 14 0.55 0.00 3.03 0.02 0.00 0.00 0.00 0.00 96.40 Average: 15 0.10 0.00 2.16 0.00 0.00 0.00 0.00 0.00 97.74
Average: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle Average: all 4.65 0.00 34.71 0.01 0.00 7.37 0.00 0.00 53.26 Average: 0 0.02 0.00 0.37 0.00 0.00 99.40 0.00 0.00 0.22 Average: 1 5.60 0.00 38.33 0.02 0.00 2.02 0.00 0.00 54.04 Average: 2 5.57 0.00 37.33 0.03 0.00 1.01 0.00 0.00 56.05 Average: 3 5.11 0.00 36.28 0.00 0.00 0.73 0.00 0.00 57.88 Average: 4 4.78 0.00 37.16 0.00 0.00 2.05 0.00 0.00 56.01 Average: 5 4.45 0.00 37.46 0.00 0.00 0.97 0.00 0.00 57.12 Average: 6 4.34 0.00 36.25 0.00 0.00 0.97 0.00 0.00 58.45 Average: 7 4.28 0.00 35.87 0.00 0.00 0.97 0.00 0.00 58.88 Average: 8 5.47 0.00 37.11 0.02 0.00 1.27 0.00 0.00 56.13 Average: 9 5.58 0.00 37.59 0.03 0.00 2.13 0.00 0.00 54.66 Average: 10 5.98 0.00 37.04 0.00 0.00 1.22 0.00 0.00 55.76 Average: 11 4.99 0.00 34.58 0.00 0.00 0.99 0.00 0.00 59.44 Average: 12 4.46 0.00 37.47 0.00 0.00 0.99 0.00 0.00 57.09 Average: 13 4.83 0.00 36.97 0.00 0.00 1.37 0.00 0.00 56.83 Average: 14 4.60 0.00 38.06 0.00 0.00 1.53 0.00 0.00 55.81 Average: 15 4.36 0.00 37.26 0.00 0.00 1.45 0.00 0.00 56.92
Average: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle Average: all 6.13 0.00 55.66 0.00 0.00 32.04 0.00 0.00 6.17 Average: 0 6.31 0.00 54.49 0.03 0.00 4.19 0.00 0.00 34.98 Average: 1 2.00 0.00 16.65 0.00 0.00 81.35 0.00 0.00 0.00 Average: 2 3.31 0.00 29.36 0.00 0.00 64.58 0.00 0.00 2.76 Average: 3 2.91 0.00 23.11 0.00 0.00 71.40 0.00 0.00 2.58 Average: 4 2.48 0.00 20.82 0.00 0.00 75.30 0.00 0.00 1.40 Average: 5 2.49 0.00 21.90 0.00 0.00 73.30 0.00 0.00 2.31 Average: 6 3.00 0.00 28.87 0.00 0.00 65.96 0.00 0.00 2.17 Average: 7 2.58 0.00 22.95 0.00 0.00 72.46 0.00 0.00 2.01 Average: 8 6.61 0.00 56.48 0.00 0.00 0.00 0.00 0.00 36.90 Average: 9 9.83 0.00 89.28 0.00 0.00 0.05 0.00 0.00 0.83 Average: 10 9.73 0.00 87.18 0.00 0.00 0.00 0.00 0.00 3.08 Average: 11 9.73 0.00 88.08 0.00 0.00 0.05 0.00 0.00 2.14 Average: 12 9.11 0.00 88.71 0.00 0.00 0.05 0.00 0.00 2.12 Average: 13 9.43 0.00 89.53 0.00 0.00 0.03 0.00 0.00 1.00 Average: 14 9.38 0.00 87.58 0.00 0.00 0.03 0.00 0.00 3.00 Average: 15 9.53 0.00 88.97 0.00 0.00 0.07 0.00 0.00 1.43
Average: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle Average: all 1.05 0.00 8.21 0.01 0.00 5.83 0.00 0.00 84.90 Average: 0 3.10 0.00 23.25 0.00 0.00 0.33 0.00 0.00 73.31 Average: 1 2.73 0.00 21.15 0.00 0.00 0.37 0.00 0.00 75.75 Average: 2 0.72 0.00 4.93 0.00 0.00 92.35 0.00 0.00 2.00 Average: 3 1.27 0.00 9.81 0.00 0.00 0.10 0.00 0.00 88.82 Average: 4 0.15 0.00 1.87 0.10 0.00 0.07 0.00 0.00 97.82 Average: 5 0.07 0.00 1.04 0.00 0.00 0.07 0.00 0.00 98.82 Average: 6 0.02 0.00 0.53 0.00 0.00 0.03 0.00 0.00 99.42 Average: 7 0.00 0.00 0.23 0.00 0.00 0.00 0.00 0.00 99.77 Average: 8 0.23 0.00 1.96 0.00 0.00 0.00 0.00 0.00 97.81 Average: 9 0.08 0.00 0.60 0.00 0.00 0.00 0.00 0.00 99.32 Average: 10 8.38 0.00 65.07 0.00 0.00 0.00 0.00 0.00 26.56 Average: 11 0.00 0.00 0.36 0.00 0.00 0.00 0.00 0.00 99.64 Average: 12 0.03 0.00 0.23 0.00 0.00 0.00 0.00 0.00 99.73 Average: 13 0.00 0.00 0.19 0.00 0.00 0.00 0.00 0.00 99.81 Average: 14 0.00 0.00 0.12 0.00 0.00 0.00 0.00 0.00 99.88 Average: 15 0.02 0.00 0.10 0.00 0.00 0.00 0.00 0.00 99.88
Average: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle Average: all 6.27 0.00 53.65 0.00 0.00 32.33 0.00 0.00 7.74 Average: 0 7.05 0.00 59.70 0.00 0.00 26.18 0.00 0.00 7.07 Average: 1 5.44 0.00 43.33 0.00 0.00 44.54 0.00 0.00 6.69 Average: 2 5.49 0.00 43.06 0.00 0.00 43.38 0.00 0.00 8.07 Average: 3 5.48 0.00 44.90 0.00 0.00 42.94 0.00 0.00 6.67 Average: 4 4.74 0.00 43.27 0.00 0.00 45.14 0.00 0.00 6.85 Average: 5 4.83 0.00 41.90 0.00 0.00 46.74 0.00 0.00 6.53 Average: 6 5.04 0.00 44.73 0.00 0.00 43.68 0.00 0.00 6.56 Average: 7 4.85 0.00 44.68 0.00 0.00 45.22 0.00 0.00 5.25 Average: 8 7.60 0.00 61.50 0.02 0.00 22.79 0.00 0.00 8.08 Average: 9 7.40 0.00 61.31 0.00 0.00 22.92 0.00 0.00 8.37 Average: 10 7.74 0.00 60.62 0.00 0.00 22.64 0.00 0.00 9.00 Average: 11 8.22 0.00 61.02 0.00 0.00 22.13 0.00 0.00 8.63 Average: 12 6.53 0.00 62.42 0.00 0.00 22.09 0.00 0.00 8.97 Average: 13 6.68 0.00 62.75 0.00 0.00 22.13 0.00 0.00 8.43 Average: 14 6.62 0.00 62.41 0.00 0.00 22.69 0.00 0.00 8.28 Average: 15 6.64 0.00 60.66 0.00 0.00 22.38 0.00 0.00 10.32
对于UDP测试在IRQ affinity上性能的下降, 查阅了内核源码(drivers/net/bnx2.c)及资料, bnx2 网卡的RSS hash不支持对UDP的端口进行计算,从而导致单独启用IRQ affinity的时候(这时候由硬件进行hash计算), UDP的数据只被hash了IP地址而导致数据包的转发出现集中在某个CPU的现象. 这是此次测试的局限所在,由于测试只是一台服务器端及一台客户端,所有UDP的IP地址都相同,无法体现UDP性能在单独启用IRQ affinity的性能提升. 但RPS/RFS的hash计算不受硬件影响,故而能体现性能提升. 对于实际应用中,服务器与多台客户端交互的情形,应该不受bnx2的RSS hash影响(以上只是针对bnx2网卡的特定问题)
什么是interrupt
是一种硬件和CPU的沟通方式,还有一种方式较轮循,即CPU定时监测硬件状态并做出处理,这种方式比较消耗CPU;
由硬件产生的电信号,经由中断控制器转发给CPU ,而每个硬件都有一个IRQ以作区分;
Linux 2.4支持把不同硬件中断请求分配到特定CPU上,称为SMP IRQ Affinity
而大部分linux都没有配置网络中端负载均衡,即所有网络终端请求全部在一个CPU上处理,当网络繁忙时容易形成瓶颈;
设置SMP affinity
每个硬件设备的中断设置信息保存于/proc/irq,其中每个数字代表一个硬件的IRQ
[oracle@ irq]$ pwd
/proc/irq
[oracle@ irq]$ ls
0 10 12 14 17 20 23 4 5 62 67 69 70 72 74 76 78 8 81 83 85 87 89 90 default_smp_affinity
1 11 13 15 2 22 3 48 6 66 68 7 71 73 75 77 79 80 82 84 86 88 9 91
可通过/proc/interrupts查看每个CPU的中断处理情况
# cat /proc/interrupts
CPU0 CPU1 CPU2 CPU3
65: 20041 0 0 0 IR-PCI-MSI-edge eth0-tx-0
66: 20232 0 0 0 IR-PCI-MSI-edge eth0-tx-1
67: 20105 0 0 0 IR-PCI-MSI-edge eth0-tx-2
68: 20423 0 0 0 IR-PCI-MSI-edge eth0-tx-3
69: 21036 0 0 0 IR-PCI-MSI-edge eth0-rx-0
70: 20201 0 0 0 IR-PCI-MSI-edge eth0-rx-1
71: 20587 0 0 0 IR-PCI-MSI-edge eth0-rx-2
72: 20853 0 0 0 IR-PCI-MSI-edge eth0-rx-3
首先确认其当前设置
# cat /proc/irq/65/smp_affinity
00000001
-- 每位代表代表4个CPU,其和CPU映射方式如下
Binary Hex
CPU 0 0001 1
CPU 1 0010 2
CPU 2 0100 4
CPU 3 1000 8
-----------------------
all 1111 f
修改其smp_affinity
如果开启了irqbalance则需要先将其停止,可将一个设备绑定到多个CPU上
echo 000002 > /proc/irq/65/smp_affinity # eth0-tx-0
--将eth0绑定到CPU1
echo 000006 > /proc/irq/65/smp_affinity # eth0-tx-0
--将eth0绑定到CPU1/CPU2
查看IRQ性能
可通过/proc/interrupts查看每个CPU的中断信息;
Mpstat输出列包括%irq,而intr/s表示每秒处理的中断数
[oracle@ irq]$ mpstat -P ALL 10
Linux 2.6.32-100.26.2.el5 (.usuwb.astrazeneca.net) 01/31/2013
01:47:50 AM CPU %user %nice %sys %iowait %irq %soft %steal %idle intr/s
01:48:00 AM all 1.11 0.00 0.67 0.05 0.00 0.07 0.00 98.10 8696.01
01:48:00 AM 0 0.30 0.00 0.20 0.20 0.00 0.00 0.00 99.30 0.00
01:48:00 AM 1 1.79 0.00 0.99 0.10 0.00 0.00 0.00 97.12 0.10
01:48:00 AM 2 1.10 0.00 1.99 0.00 0.00 0.00 0.00 96.91 0.50
01:48:00 AM 3 1.30 0.00 0.70 0.00 0.00 0.10 0.00 97.90 0.00
01:48:00 AM 4 0.20 0.00 0.10 0.00 0.00 0.00 0.00 99.70 0.00
Vmstat中的in代表中断
$ vmstat 1
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
r b swpd free buff cache si so bi bo in cs us sy id wa st
4 0 140 2915476 341288 3951700 0 0 0 0 1057 523 19 81 0 0 0
4 0 140 2915724 341296 3951700 0 0 0 0 1048 546 19 81 0 0 0
4 0 140 2915848 341296 3951700 0 0 0 0 1044 514 18 82 0 0 0
4 0 140 2915848 341296 3951700 0 0 0 24 1044 564 20 80 0 0 0
4 0 140 2915848 341296 3951700 0 0 0 0 1060 546 18 82 0 0 0
从上面的数据可以看出几点:
$ vmstat 1
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
r b swpd free buff cache si so bi bo in cs us sy id wa st
14 0 140 2904316 341912 3952308 0 0 0 460 1106 9593 36 64 1 0 0
17 0 140 2903492 341912 3951780 0 0 0 0 1037 9614 35 65 1 0 0
20 0 140 2902016 341912 3952000 0 0 0 0 1046 9739 35 64 1 0 0
17 0 140 2903904 341912 3951888 0 0 0 76 1044 9879 37 63 0 0 0
16 0 140 2904580 341912 3952108 0 0 0 0 1055 9808 34 65 1 0 0
从上面的数据可以看出几点:
style="font-family:宋体;font-size:small;">
在前阵子看到HelloDB的一篇文章“MySQL单机多实例方案”中提到:
因为单机运行多个实例,必须对网络进行优化,我们通过多个的IP的方式,将多个MySQL实例绑定在不同的网卡上,从而提高整体的网络能力。还有一种更高级的做法是,将不同网卡的中断与CPU绑定,这样可以大幅度提升网卡的效率。
于是,对“将不同网卡的中断与CPU绑定,这样可以大幅度提升网卡的效率”比较感兴趣,所以找了点资料了解一下。先总结如下:
1. 不同的设备一般都有自己的IRQ号码(当然一个设备还有可能有多个IRQ号码)
通过命令:cat /proc/interrupts查看
如:cat /proc/interrupts | grep -e “CPU\|eth4″
2. 中断的smp affinity在cat /proc/irq/$Num/smp_affinity
可以echo “$bitmask” > /proc/irq/$num/smp_affinity来改变它的值。
注意smp_affinity这个值是一个十六进制的bitmask,它和cpu No.序列的“与”运算结果就是将affinity设置在那个(那些)CPU了。(也即smp_affinity中被设置为1的位为CPU No.)
比如:我有8个逻辑core,那么CPU#的序列为11111111 (从右到左依次为#0~#7的CPU)
如果cat /proc/irq/84/smp_affinity的值为:20(二进制为:00100000),则84这个IRQ的亲和性为#5号CPU。
每个IRQ的默认的smp affinity在这里:cat /proc/irq/default_smp_affinity
另外,cat /proc/irq/$Num/smp_affinity_list 得到的即是CPU的一个List。
3. 默认情况下,有一个irqbalance在对IRQ进行负载均衡,它是/etc/init.d/irqbalance
在某些特殊场景下,可以根据需要停止这个daemon进程。
4. 如果要想提高性能,将IRQ绑定到某个CPU,那么最好在系统启动时,将那个CPU隔离起来,不被scheduler通常的调度。
可以通过在Linux kernel中加入启动参数:isolcpus=cpu-list来将一些CPU隔离起来。
参考资料:
http://kernel.org/doc/Documentation/IRQ-affinity.txt
http://kernel.org/doc/Documentation/kernel-parameters.txt
前天我们讨论了如何绑定特定的硬件中断到特定的 CPU 上, 分散和平衡各个中断到不同的 CPU 上以获取更大性能的处理能力。上篇限于篇幅的关系,没有来得及进一步说明 “echo 2 > /proc/irq/90/smp_affinity” 中的 ”2“ 是怎么来的,这其实是个二进制数字,代表 00000010,00000001 代表 CPU0 的话,00000010 就代表 CPU0, “echo 2 > /proc/irq/90/smp_affinity” 的意思就是说把 90 中断绑定到 00000010(CPU1)上。所以各个 CPU 用二进制和十六进制表示就是:
Binary Hex CPU 0 00000001 1 CPU 1 00000010 2 CPU 2 00000100 4 CPU 3 00001000 8
如果我想把 IRQ 绑定到 CPU2 上就是 00000100=4:
# echo "4" > /proc/irq/90/smp_affinity
如果我想把 IRQ 同时平衡到 CPU0 和 CPU2 上就是 00000001+00000100=00000101=5
# echo "5" > /proc/irq/90/smp_affinity
需要注意的是,在手动绑定 IRQ 到 CPU 之前需要先停掉 irqbalance 这个服务,irqbalance 是个服务进程、是用来自动绑定和平衡 IRQ 的:
# /etc/init.d/irqbalance stop
还有一个限制就是,IO-APIC 有两种工作模式:logic 和 physical(但是如何配置工作模式,我还不太清楚,请知道的朋友告知一下,^_^),在 logic 模式下 IO-APIC 可以同时分布同一种 IO 中断到8颗 CPU (core) 上(受到 bitmask 寄存器的限制,因为 bitmask 只有8位长。);在 physical 模式下不能同时分布同一中断到不同 CPU 上,比如,不能让 eth0 中断同时由 CPU0 和 CPU1 处理,这个时候只能定位 eth0 到 CPU0、eth1 到 CPU1,也就是说 eth0 中断不能像 logic 模式那样可以同时由多个 CPU 处理。
smp_affinity 文件默认是全部ffffffff,8个f就是16的8次方位,一般一台机就几只cpu,所以够了,echo 3 > /proc/irq/24/smp_affinity 就是分配第一第二只cpu给该irq。
smp_affinity 具体定义:
Binding IRQ’s to a group of CPU’s is a new feature of the 2.4 kernel. While it was originally developed as part of Red Hat Content Accelerator, it is now a generic and independent kernel feature. Every IRQ source in Linux has an entry in /proc/irq directory. For example, the settings for IRQ 40 is stored in /proc/irq/40. IRQ affinity, or IRQ bindings, is configured though the smp_affinity setting in that directory. For example, the smp_affinity for IRQ 40 is in /proc/irq/40/smp_affinity. The value of the smp_affinity setting is a bitmask of all CPU’s that are permitted as a resource for the given IRQ. The default value for smp_affinity is the HEX value 0xffffffff. This means the processes for the IRQ are sent to all CPU’s. You are not allowed to turn off all CPU’s for an IRQ. If the IRQ controller does not support IRQ affinity, the value can not be changed from the default. If multiple CPU’s are defined, then the IRQ source uses the least busy CPU. This is called ‘lowest priority APIC routing.’ IRQ affinity is achieved by binding an IRQ to a specific CPU or group of CPU’s by echoing a HEX value to smp_affinity for the IRQ.