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网卡的特定问题)