打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Linux内核 RPS/RFS功能详细测试分析
标签:网络linux
2014-09-19 16:40 291人阅读评论(0)举报
分类:
网络(11)
目录(?)[+]
RPS和RFS
RPS 全称是 Receive Packet Steering, 这是Google工程师 Tom Herbert (therbert@google.com )提交的内核补丁, 在2.6.35进入Linux内核. 这个patch采用软件模拟的方式,实现了多队列网卡所提供的功能,分散了在多CPU系统上数据接收时的负载, 把软中断分到各个CPU处理,而不需要硬件支持,大大提高了网络性能。
RFS 全称是 Receive Flow Steering, 这也是Tom提交的内核补丁,它是用来配合RPS补丁使用的,是RPS补丁的扩展补丁,它把接收的数据包送达应用所在的CPU上,提高cache的命中率。
这两个补丁往往都是一起设置,来达到最好的优化效果, 主要是针对单队列网卡多CPU环境(多队列多重中断的网卡也可以使用该补丁的功能,但多队列多重中断网卡有更好的选择:SMP IRQ affinity)
原理
RPS: RPS实现了数据流的hash归类,并把软中断的负载均衡分到各个cpu,实现了类似多队列网卡的功能。由于RPS只是单纯的把同一流的数据包分发给同一个CPU核来处理了,但是有可能出现这样的情况,即给该数据流分发的CPU核和执行处理该数据流的应用程序的CPU核不是同一个:数据包均衡到不同的cpu,这个时候如果应用程序所在的cpu和软中断处理的cpu不是同一个,此时对于cpu cache的影响会很大。那么RFS补丁就是用来确保应用程序处理的cpu跟软中断处理的cpu是同一个,这样就充分利用cpu的cache。
应用RPS之前: 所有数据流被分到某个CPU, 多CPU没有被合理利用, 造成瓶颈
应用RPS之后: 同一流的数据包被分到同个CPU核来处理,但可能出现cpu cache迁跃
应用RPS+RFS之后: 同一流的数据包被分到应用所在的CPU核
必要条件
使用RPS和RFS功能,需要有大于等于2.6.35版本的Linux kernel.
如何判断内核版本?
1
2
$uname-r
2.6.38-2-686-bigmem
对比测试
类别测试客户端测试服务端
型号BladeCenter HS23pBladeCenter HS23p
CPUXeon E5-2609Xeon E5-2630
网卡Broadcom NetXtreme II BCM5709S Gigabit EthernetEmulex Corporation OneConnect 10Gb NIC
内核3.2.0-2-amd643.2.0-2-amd64
内存62GB66GB
系统Debian 6.0.4Debian 6.0.5
超线程否是
CPU核46
驱动bnx2be2net
客户端: netperf
服务端: netserver
RPS cpu bitmap测试分类: 0(不开启rps功能), one cpu per queue(每队列绑定到1个CPU核上), all cpus per queue(每队列绑定到所有cpu核上), 不同分类的设置值如下
0(不开启rps功能)/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
one cpu per queue(每队列绑定到1个CPU核上)/sys/class/net/eth0/queues/rx-0/rps_cpus 00000001/sys/class/net/eth0/queues/rx-1/rps_cpus 00000002/sys/class/net/eth0/queues/rx-2/rps_cpus 00000004/sys/class/net/eth0/queues/rx-3/rps_cpus 00000008/sys/class/net/eth0/queues/rx-4/rps_cpus 00000010/sys/class/net/eth0/queues/rx-5/rps_cpus 00000020/sys/class/net/eth0/queues/rx-6/rps_cpus 00000040/sys/class/net/eth0/queues/rx-7/rps_cpus 00000080/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
all cpus per queue(每队列绑定到所有cpu核上)/sys/class/net/eth0/queues/rx-0/rps_cpus 000000ff/sys/class/net/eth0/queues/rx-1/rps_cpus 000000ff/sys/class/net/eth0/queues/rx-2/rps_cpus 000000ff/sys/class/net/eth0/queues/rx-3/rps_cpus 000000ff/sys/class/net/eth0/queues/rx-4/rps_cpus 000000ff/sys/class/net/eth0/queues/rx-5/rps_cpus 000000ff/sys/class/net/eth0/queues/rx-6/rps_cpus 000000ff/sys/class/net/eth0/queues/rx-7/rps_cpus 000000ff/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秒
TCP_RR 1 byte: 测试TCP 小数据包 request/response的性能1
netperf -t TCP_RR -H $serverip -c -C -l 60
UDP_RR 1 byte: 测试UDP 小数据包 request/response的性能1
netperf -t UDP_RR -H $serverip -c -C -l 60
TCP_RR 256 byte: 测试TCP 大数据包 request/response的性能1
netperf -t TCP_RR -H $serverip -c -C -l 60 -- -r256,256
UDP_RR 256 byte: 测试UDP 大数据包 request/response的性能1
netperf -t UDP_RR -H $serverip -c -C -l 60 -- -r256,256
TPS测试结果
TCP_RR 1 byte小包测试结果
TCP_RR 256 byte大包测试结果
UDP_RR 1 byte小包测试结果
UDP_RR 256 byte大包测试结果
CPU负载变化
在测试过程中,使用mpstat收集各个CPU核的负载变化
关闭RPS/RFS: 可以看出关闭RPS/RFS时,软中断的负载都在cpu0上,并没有有效的利用多CPU的特性,导致了性能瓶颈Average: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idleAverage: all 3.65 0.00 35.75 0.05 0.01 14.56 0.00 0.00 45.98Average: 0 0.00 0.00 0.00 0.00 0.00 100.00 0.00 0.00 0.00Average: 1 4.43 0.00 37.76 0.00 0.11 11.49 0.00 0.00 46.20Average: 2 5.01 0.00 45.80 0.00 0.00 0.00 0.00 0.00 49.19Average: 3 5.11 0.00 45.07 0.00 0.00 0.00 0.00 0.00 49.82Average: 4 3.52 0.00 40.38 0.14 0.00 0.00 0.00 0.00 55.96Average: 5 3.85 0.00 39.91 0.00 0.00 0.00 0.00 0.00 56.24Average: 6 3.62 0.00 40.48 0.14 0.00 0.00 0.00 0.00 55.76Average: 7 3.87 0.00 38.86 0.11 0.00 0.00 0.00 0.00 57.16
每队列关联到一个CPU TCP_RR: 可以看出软中断负载已经能分散到各个CPU核上,有效利用了多CPU的特性,大大提高了系统的网络性能Average: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idleAverage: all 5.58 0.00 59.84 0.01 0.00 22.71 0.00 0.00 11.86Average: 0 2.16 0.00 20.85 0.00 0.04 72.03 0.00 0.00 4.93Average: 1 4.68 0.00 46.27 0.00 0.00 42.73 0.00 0.00 6.32Average: 2 6.76 0.00 63.79 0.00 0.00 11.03 0.00 0.00 18.42Average: 3 6.61 0.00 65.71 0.00 0.00 11.51 0.00 0.00 16.17Average: 4 5.94 0.00 67.83 0.07 0.00 11.59 0.00 0.00 14.58Average: 5 5.99 0.00 69.42 0.04 0.00 12.54 0.00 0.00 12.01Average: 6 5.94 0.00 69.41 0.00 0.00 12.86 0.00 0.00 11.78Average: 7 6.13 0.00 69.61 0.00 0.00 14.48 0.00 0.00 9.77
每队列关联到一个CPU UDP_RR: CPU负载未能均衡的分布到各个CPU, 这是由于网卡hash计算在UDP包上的不足, 详细请见本文后记部分Average: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idleAverage: all 3.01 0.00 29.84 0.07 0.01 13.35 0.00 0.00 53.71Average: 0 0.00 0.00 0.08 0.00 0.00 90.01 0.00 0.00 9.91Average: 1 3.82 0.00 32.87 0.00 0.05 12.81 0.00 0.00 50.46Average: 2 4.84 0.00 37.53 0.00 0.00 0.14 0.00 0.00 57.49Average: 3 4.90 0.00 37.92 0.00 0.00 0.16 0.00 0.00 57.02Average: 4 2.57 0.00 32.72 0.20 0.00 0.09 0.00 0.00 64.42Average: 5 2.66 0.00 33.54 0.11 0.00 0.08 0.00 0.00 63.60Average: 6 2.75 0.00 32.81 0.09 0.00 0.06 0.00 0.00 64.30Average: 7 2.71 0.00 32.66 0.17 0.00 0.06 0.00 0.00 64.40
每队列关联到所有CPU: 可以看出软中断负载已经能分散到各个CPU核上,有效利用了多CPU的特性,大大提高了系统的网络性能Average: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idleAverage: all 5.39 0.00 59.97 0.00 0.00 22.57 0.00 0.00 12.06Average: 0 1.46 0.00 21.83 0.04 0.00 72.08 0.00 0.00 4.59Average: 1 4.45 0.00 46.40 0.00 0.04 43.39 0.00 0.00 5.72Average: 2 6.84 0.00 65.62 0.00 0.00 11.39 0.00 0.00 16.15Average: 3 6.71 0.00 67.13 0.00 0.00 12.07 0.00 0.00 14.09Average: 4 5.73 0.00 66.97 0.00 0.00 10.71 0.00 0.00 16.58Average: 5 5.74 0.00 68.57 0.00 0.00 13.02 0.00 0.00 12.67Average: 6 5.79 0.00 69.27 0.00 0.00 12.31 0.00 0.00 12.63Average: 7 5.96 0.00 68.98 0.00 0.00 12.00 0.00 0.00 13.06
结果分析
以下结果只是针对测试服务器特定硬件及系统的数据,在不同测试对象的RPS/RFS测试结果可能有不同的表现
TCP性能:
在没有打开RPS/RFS的情况下,随着进程数的增加,TCP tps性能并明显没有提升,在184~188k之间。
打开RPS/RFS之后,随着RPS导致软中断被分配到所有CPU上和RFS增加的cache命中, 小数据包(1字节)及大数据包(256字节,相对小数据包而言, 而不是实际应用中的大数据包)的tps性能都有显著提升
100个进程提升40%的性能(两种RPS/RFS设置的性能结果一致), cpu负载升高40%
500个进程提升70%的性能(两种RPS/RFS设置的性能结果一致), cpu负载升高62%
1500个进程提升75%的性能(两种RPS/RFS设置的性能结果一致), cpu负载升高77%
UDP性能:
在没有打开RPS/RFS的情况下,随着进程数的增加,UDP tps性能并明显没有提升,在226~235k之间。
打开RPS/RFS之后,,随着RPS导致软中断被分配到所有CPU上和RFS增加的cache命中, 小数据包(1字节)及大数据包(256字节,相对小数据包而言, 而不是实际应用中的大数据包)的TPS性能, 在每队列关联到所有CPU的情况下有显著提升, 而每队列关联到一个CPU后反倒是导致了UDP tps性能下降1% (这是bnx2网卡不支持UDP port hash及此次测试的局限性造成的结果, 详细分析见: 后记)
每队列关联到所有CPU的情况下, 在100个进程时小包提升40%的性能, cpu负载升高60%; 大包提升33%, cpu负载升高47%
每队列关联到所有CPU的情况下, 在500个进程提小包提升62%的性能, cpu负载升高71%; 大包提升60%, cpu负载升高65%
每队列关联到所有CPU的情况下, 在1500个进程提升65%的性能, cpu负载升高75%; 大包提升64%, cpu负载升高74%
后记
UDP在每队列绑定到一个CPU时性能下降,而绑定到所有CPU时,却有性能提升,这一问题涉及到几个因素,当这几个因素凑一起时,导致了这种奇特的表现。
此次测试的局限性:本次测试是1对1的网络测试,产生的数据包的IP地址都是相同的
bnx2网卡在RSS hash上,不支持UDP Port,也就是说,网卡在对TCP数据流进行队列选择时的hash包含了ip和port, 而在UDP上的hash, 只有IP地址,导致了本次测试(上面的局限性影响)的UDP数据包的hash结果都是一样的,数据包被转送到同一条队列。
单单上面两个因素,还无法表现出UDP在每队列绑定到一个CPU时性能下降,而绑定到所有CPU时,却有性能提升的现象。 因为RPS/RFS本身也有hash计算,也就是进入队列后的数据包,还需要经过RPS/RFS的hash计算(这里的hash支持udp port), 然后进行第二次数据包转送选择;如果每队列绑定到一个CPU, 系统直接跳过第二次hash计算,数据包直接分配到该队列关联的CPU处理,也就导致了在第一次hash计算后被错误转送到某一队列的UDP数据包,将直接送到cpu处理,导致了性能的下降; 而如果是每队列绑定到所有CPU, 那么进入队列后的数据包会在第二次hash时被重新分配,修正了第一次hash的错误选择。
相关对比测试
1. SMP IRQ affinity: http://www.igigo.net/archives/231
参考资料
Software receive packet steering
Receive Packet Steering
Receive packet steering
Receive Flow Steering
linux kernel 2.6.35中RFS特性详解
Linux 2.6.35 新增特性 RPS RFS
kernel/Documentation/networking/scaling.txt
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Linux内核网络UDP数据包发送(四)——Linux netdevice 子系统
网卡多队列
Linux中国
十年码农内功:收包(二)
[原创] 在多核系统上网络数据转发实验和一点思考
多队列网卡简介
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服