Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1796378
  • 博文数量: 306
  • 博客积分: 3133
  • 博客等级: 中校
  • 技术积分: 3932
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-19 16:50
文章分类

全部博文(306)

文章存档

2018年(7)

2017年(18)

2016年(39)

2015年(35)

2014年(52)

2013年(39)

2012年(22)

2011年(29)

2010年(53)

2009年(12)

分类: LINUX

2015-09-06 16:01:02

SMP IRQ affinity

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压力,提高数据处理速度。

    • 不使用SMP IRQ affinity

    • 使用SMP IRQ affinity

使用前提

  • 需要多CPU的系统
  • 需要大于等于2.4的Linux 内核

相关设置文件

1. /proc/irq/IRQ#/smp_affinity

    • /proc/irq/IRQ#/smp_affinity 和 /proc/irq/IRQ#/smp_affinity_list 指定了哪些CPU能够关联到一个给定的IRQ源. 这两个文件包含了这些指定cpu的cpu位掩码(smp_affinity)和cpu列表(smp_affinity_list). 不允许关闭所有CPU, 同时如果IRQ控制器不支持中断请求亲和(IRQ affinity),则这些设置的值将保持不变(既关联到所有CPU). 设置方法如下
1
echo $bitmask > /proc/irq/IRQ#/smp_affinity
    • 示例(把44号中断绑定到前4个CPU(CPU0-3)上面)
1
echo f > /proc/irq/44/smp_affinity

2. /proc/irq/IRQ#/smp_affinity_list

    • 设置该文件取得的效果与/proc/irq/IRQ#/smp_affinity是一致的,它们两者是联动关系(既设置其中之一,另一个文件也随着改变), 有些系统可能没有该文件, 设置方法如下
1
echo $cpuindex1-$cpuindex2 >/proc/irq/IRQ#/smp_affinity_list
    • 示例(把44号中断绑定到前4个CPU(CPU0-3)上面)
1
echo 0-3 > /proc/irq/44/smp_affinity_list

3. /proc/irq/default_smp_affinity

  • /proc/irq/default_smp_affinity 指定了默认情况下未激活的IRQ的中断亲和掩码(affinity mask).一旦IRQ被激活,它将被设置为默认的设置(即default_smp_affinity中记录的设置). 该文件能被修改. 默认设置是0xffffffff.

bitmask计算方法

首先我们来看看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的系统为例:

    • “f” 是十六进制的值, 二进制是”1111”. 二进制中的每个位代表了服务器上的每个CPU. 那么能用以下方法表示每个CPU
           二进制  十六进制
   CPU 0   0001    1
   CPU 1   0010    2
   CPU 2   0100    4
   CPU 3   1000    8
    • 结合这些位掩码(简单来说就是直接对十六进制值做加法), 我们就能一次定位多个CPU。 例如, 我想同时表示CPU0和CPU2, bitmask结果就是:
           二进制       十六进制
   CPU 0    0001         1
 + CPU 2    0100         4
   -----------------------
   bitmask  0101         5
    • 如果我想一次性表示所有4个CPU,bitmask结果是:
           二进制       十六进制
   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
  1. 客户端: netperf
  2. 服务端: netserver
  3. 测试分类: 不开启IRQ affinity和RPS/RFS, 单独开启IRQ affinity, 单独开启RPS/RFS,同时开启IRQ affinity和RPS/RFS, 不同分类设置值如下
    1. 不开启IRQ affinity和RPS/RFS
/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
    1. 单独开启IRQ affinity
/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
    1. 单独开启RPS/RFS
/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
    1. 同时开启IRQ affinity和RPS/RFS
/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. TCP_RR 1 byte: 测试TCP 小数据包 request/response的性能
1
netperf -t TCP_RR -H $serverip -c -C -l 60
    1. UDP_RR 1 byte: 测试UDP 小数据包 request/response的性能
1
netperf -t UDP_RR -H $serverip -c -C -l 60
    1. TCP_RR 256 byte: 测试TCP 大数据包 request/response的性能
1
netperf -t TCP_RR -H $serverip -c -C -l 60 -- -r256,256
    1. UDP_RR 256 byte: 测试UDP 大数据包 request/response的性能
1
netperf -t UDP_RR -H $serverip -c -C -l 60 -- -r256,256

测试结果

    1. TCP_RR 1 byte小包测试

    1. TCP_RR 256 byte大包测试

    1. UDP_RR 1 byte小包测试

    1. UDP_RR 256 byte大包测试

 

CPU核负载的变化

以小数据包1500进程测试的CPU(除了明确指明类型,否则这里的负载都是TCP_RR测试的负载)负载数据为示例

    • 不开启IRQ affinity和RPS/RFS: 软中断集中在第一个CPU上,导致了性能瓶颈
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
    • 单独开启RPS/RFS: 软中断主要集中在CPU0上,但有少许分布在其他CPU上
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
    • 单独开启IRQ affinity, TCP_RR测试: 软中断负载比较均匀的分散到前面8个CPU之上(与bitmask设置一致)
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
    • 单独开启IRQ affinity, UDP_RR测试: 软中断负载不能均匀的分散到前面8个CPU之上,主要分布在CPU2上,导致了瓶颈,性能下降(下降原因请见本文测试的局限性部分)
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
    • 同时开启IRQ affinity和RPS/RFS: 软中断负载比较均匀的分散到各个CPU之上
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

结果分析

1. TCP_RR TPS小数据包性能

  • 单独开启RPS/RFS分别提升60%,145%,200%(依次对应100进程,500进程,1500进程,下同)
  • 单独开启IRQ affinity分别提升135%, 343%, 443%
  • 同时开启RPS/RFS和IRQ affinity分别提升148%, 346%, 372%

2. TCP_RR TPS大数据包性能

  • 单独开启RPS/RFS分别提升76%,77%,89%
  • 单独开启IRQ affinity分别提升79%, 77%, 88%
  • 同时开启RPS/RFS和IRQ affinity分别提升79%, 77%, 88%

3. UDP_RR TPS小数据包性能

  • 单独开启RPS/RFS分别提升44%,103%,94%
  • 单独开启IRQ affinity性能分别下降11%, 8%, 8% (这是此次测试的局限造成, 详细分析见: 测试的局限性)
  • 同时开启RPS/RFS和IRQ affinity分别提升65%, 130%, 137%

4. UDP_RR TPS小数据包性能

  • 单独开启RPS/RFS分别提升55%,53%,61%
  • 单独开启IRQ affinity性能分别下降5%, 4%, 4%
  • 同时开启RPS/RFS和IRQ affinity分别提升55%, 51%, 53%
  1. TCP 小数据包应用上,单独开启IRQ affinity能获得最大的性能提升,随着进程数的增加,IRQ affinity的优势越加明显.
  2. UDP 小数据包方面,由于此次测试的局限,无法真实体现实际应用中的单独开启IRQ affinity而获得的性能提升, 但用RPS/RFS配合IRQ affinity,也能获得大幅度的性能提升;
  3. TCP 大数据包应用上,单独开启IRQ affinity性能提升没有小数据包那么显著,但也有接近80%的提升, 基本与单独开启RPS/RFS的性能持平, 根据实验的数据计算所得,此时网卡流量约为88MB,还没达到千兆网卡的极限。
  4. UDP 大数据包应用上,也是同样受测试局限性的影响,无法真实体现实际应用中的单独开启IRQ affinity而获得的性能提升, 但用RPS/RFS配合IRQ affinity,也能获得大幅度的性能提升

测试的局限性

对于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

-- 每位代表代表4CPU,其和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

从上面的数据可以看出几点:

  1. interruptsin)非常高,context switchcs)比较低,说明这个 CPU 一直在不停的请求资源;
  2. system timesy)一直保持在 80 以上,而且上下文切换较低(cs),说明某个进程可能一直霸占着 CPU(不断请求资源);
  3. run queuer)刚好在4个。

$ 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

从上面的数据可以看出几点:

  1. context switchcs)比 interruptsin)要高得多,说明内核不得不来回切换进程;
  2. 进一步观察发现 system timesy)很高而 user timeus)很低,而且加上高频度的上下文切换(cs),说明正在运行的应用程序调用了大量的系统调用(system call);
  3. run queuer)在14个线程以上,按照这个测试机器的硬件配置(四核),应该保持在12个以内。

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 具体定义:

IRQ 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.




阅读(1870) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~