Linux RPS RFS

Stella981
• 阅读 570

随着单核CPU速度已经达到极限,CPU向多核方向发展,要持续提高网络处理带宽,传统的提升硬件设备、智能处理(如GSO、TSO、UFO)处理办法已不足够。如何充分利用多核优势来进行并行处理提高网络处理速度就是RPS解决的课题。以一个具有8核CPU和一个NIC的,连接在网络中的主机来说,对于由该主机产生并通过NIC发送到网络中的数据,CPU核的并行性是自热而然的事情:

Linux RPS RFS

问题主要在于当该主机通过NIC收到从网络发往本机的数据包时,应该将数据包分发给哪个CPU核来处理(有些具有多条接收队列和多重中断线路的NIC可以帮助数据包并行分发,这里考虑普通的NIC,普通的NIC通过RPS来模拟实现并行分发):

Linux RPS RFS

普通的NIC来分发这些接收到的数据包到CPU核处理需要一定的知识智能以帮助提升性能,如果数据包被任意的分配给某个CPU核来处理就可能会导致所谓的“CACHELINE-PINGPONG”现象,这时候RPS就出现了。

RPS全称是Receive Packet Steering, 这是Google工程师Tom Herbert提交的内核补丁, 在2.6.35进入Linux内核. 这个patch采用软件模拟的方式,实现了多队列网卡所提供的功能,分散了在多CPU系统上数据接收时的负载, 把软中断分到各个CPU处理,而不需要硬件支持,大大提高了网络性能。RPS实现了数据流的hash归类,它通过数据包相关的信息(比如IP地址和端口号)来创建CPU核分配的hash表项,当一个数据包从NIC转到内核网络子系统时就从该hash表内获取其对应分配的CPU核(首次会创建表项)。并把软中断的负载均衡分到各个cpu,实现了类似多队列网卡的功能。

Linux RPS RFS

由于RPS只是单纯的把同一流的数据包分发给同一个CPU核来处理了,但是有可能出现这样的情况,即给该数据流分发的CPU核和执行处理该数据流的应用程序的CPU核不是同一个:数据包均衡到不同的cpu,这个时候如果应用程序所在的cpu和软中断处理的cpu不是同一个,此时对于cpu cache的影响会很大。这时候就需要RFS来配合使用了,这也是Tom提交的内核补丁,它是用来配合RPS补丁使用的,是RPS补丁的扩展补丁,它把接收的数据包送达应用所在的CPU上,提高cache的命中率。这两个补丁往往都是一起设置,来达到最好的优化效果, 主要是针对单队列网卡多CPU环境。

Linux RPS RFS

要使用RPS和RFS功能,需要有大于等于2.6.35版本的Linux kernel,刚好手中有一台机器可以测试一下,配置信息如下:

机器型号:PowerEdge R610
CPU型号:Intel Xeon E5606 (4核) 
网卡型号:Broadcom Corporation NetXtreme II BCM5709 Gigabit Ethernet
内核版本:3.2.0-23
系统内存:4G
操作系统:ubuntu12.04

内核关于RPS/RFS有如下两段话:

For a single queue device, a typical RPS configuration would be to set
the rps_cpus to the CPUs in the same memory domain of the interrupting
CPU. If NUMA locality is not an issue, this could also be all CPUs in
the system. At high interrupt rate, it might be wise to exclude the
interrupting CPU from the map since that already performs much work.

For a multi-queue system, if RSS is configured so that a hardware
receive queue is mapped to each CPU, then RPS is probably redundant
and unnecessary. If there are fewer hardware queues than CPUs, then
RPS might be beneficial if the rps_cpus for each queue are the ones that
share the same memory domain as the interrupting CPU for that queue.

先测试不开启RPS时的情况,默认情况下RPS是没有开启的,所以可以直接测试,测试用了12个实例来测试,因为客户端连接比较少,所以数据看起来不会有很大的波动。

netperf -t TCP_RR -H 10.1.6.234 -c -C -l 100

09:05:28 AM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
09:05:29 AM  all    2.47    0.00   26.92    0.00    0.00   10.16    0.00    0.00   60.44
09:05:29 AM    0    2.53    0.00   32.91    0.00    0.00   39.24    0.00    0.00   25.32
09:05:29 AM    1    4.40    0.00   32.97    0.00    0.00    5.49    0.00    0.00   57.14
09:05:29 AM    2    1.05    0.00   26.32    0.00    0.00    1.05    0.00    0.00   71.58
09:05:29 AM    3    2.02    0.00   18.18    0.00    0.00    0.00    0.00    0.00   79.80

09:05:29 AM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
09:05:30 AM  all    2.34    0.00   24.56    0.00    0.29    7.89    0.00    0.00   64.91
09:05:30 AM    0    2.74    0.00   35.62    0.00    1.37   31.51    0.00    0.00   28.77
09:05:30 AM    1    3.66    0.00   28.05    0.00    1.22    4.88    0.00    0.00   62.20
09:05:30 AM    2    1.08    0.00   24.73    0.00    0.00    0.00    0.00    0.00   74.19
09:05:30 AM    3    2.15    0.00   10.75    0.00    0.00    0.00    0.00    0.00   87.10

09:05:30 AM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
09:05:31 AM  all    1.73    0.00   27.09    0.00    0.29    7.78    0.00    0.00   63.11
09:05:31 AM    0    2.60    0.00   36.36    0.00    1.30   32.47    0.00    0.00   27.27
09:05:31 AM    1    2.22    0.00   38.89    0.00    0.00    2.22    0.00    0.00   56.67
09:05:31 AM    2    2.30    0.00   19.54    0.00    0.00    0.00    0.00    0.00   78.16
09:05:31 AM    3    0.00    0.00   15.96    0.00    0.00    0.00    0.00    0.00   84.04

可以看到软中断(soft)主要集中在cpu0、cpu1上面。

接下来测试开启RPS/RFS的情况,采用每个队列绑定到所有cpu核上。

09:11:47 AM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
09:11:48 AM  all    1.52    0.00   30.70    0.00    0.61    6.08    0.00    0.00   61.09
09:11:48 AM    0    1.30    0.00   27.27    0.00    1.30    7.79    0.00    0.00   62.34
09:11:48 AM    1    2.47    0.00   30.86    0.00    0.00    7.41    0.00    0.00   59.26
09:11:48 AM    2    0.00    0.00   35.29    0.00    0.00    4.71    0.00    0.00   60.00
09:11:48 AM    3    3.49    0.00   29.07    0.00    0.00    6.98    0.00    0.00   60.47

09:11:48 AM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
09:11:49 AM  all    2.40    0.00   31.14    0.00    0.00    7.19    0.00    0.00   59.28
09:11:49 AM    0    2.53    0.00   27.85    0.00    1.27    8.86    0.00    0.00   59.49
09:11:49 AM    1    2.38    0.00   32.14    0.00    0.00    9.52    0.00    0.00   55.95
09:11:49 AM    2    2.27    0.00   34.09    0.00    0.00    4.55    0.00    0.00   59.09
09:11:49 AM    3    2.35    0.00   29.41    0.00    0.00    5.88    0.00    0.00   62.35

09:11:49 AM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
09:11:50 AM  all    2.74    0.00   28.66    0.00    0.30    7.62    0.00    0.00   60.67
09:11:50 AM    0    2.56    0.00   26.92    0.00    0.00   10.26    0.00    0.00   60.26
09:11:50 AM    1    2.41    0.00   30.12    0.00    1.20    8.43    0.00    0.00   57.83
09:11:50 AM    2    2.44    0.00   30.49    0.00    0.00    4.88    0.00    0.00   62.20
09:11:50 AM    3    2.44    0.00   28.05    0.00    0.00    6.10    0.00    0.00   63.41

可以看到软中断(soft)在4个核上面都有分布。

参考连接:

http://www.ibm.com/developerworks/cn/linux/l-netperf/index.html
http://www.pagefault.info/?p=115?
http://www.mjmwired.net/kernel/Documentation/networking/scaling.txt
http://www.igigo.net/archives/204?

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Python的多任务编程
前言Python程序代码都是按自上而下的顺序加载并执行的,但实际需要代码处理的任务并不都是需要按部就班的顺序执行,通常为提高代码执行的效率,需要多个代码执行任务同时执行,也就是多任务编程的需求。基本的计算机模型是由CPU、RAM及各种资源(键盘、硬盘、显卡、网卡等)组成,代码的执行过程,实际就是CPU和相关寄存器及RAM之间的相关处理的过程。在单核CPU场景
Stella981 Stella981
2年前
Python实现多进程
Python可以实现多线程,但是因为GlobalInterpreterLock(GIL),Python的多线程只能使用一个CPU内核,即一个时间只有一个线程在运行,多线程只是不同线程之间的切换,对多核CPU来说,就是巨大的浪费。如4核CPU,实际上只利用了一个核,CPU利用率只有25%。要充分利用多核CPU,可以实现Python的多进程。首先,im
Stella981 Stella981
2年前
Linux日常运维小结
1\.如何看当前Linux系统有几颗物理CPU和每颗CPU的核数?物理cpu个数:cat/proc/cpuinfo|grepc'physicalid'CPU一共有多少核:grepcprocessor/proc/cpuinfo将CPU的总核数除以物理CPU的个数,得到每颗CPU的核数。2\.查看系统负载有两个常用的命
Wesley13 Wesley13
2年前
Java 线程基础,从这篇开始
!(https://oscimg.oschina.net/oscnet/up9e63e77ec6426dd7cc456a5caf35dc0d18b.png)线程作为操作系统中最少调度单位,在当前系统的运行环境中,一般都拥有多核处理器,为了更好的充分利用CPU,掌握其正确使用方式,能更高效的使程序运行。同时,在Java面试中,也是极其重要的
Stella981 Stella981
2年前
Nginx 作为web server 的优化要点
常用优化要点nginx使用的是固定数量的workers,每个worker都处理进入的请求。最佳实践是每个CPU内核配置一个worker.如何知道您的系统有几个CPU?$ grep ^processor /proc/cpuinfo | wc l对于一个四核处理器,配置文件类似:\Oneworkerper
Stella981 Stella981
2年前
Noark入门之线程模型
0x00单线程多进程单线程与单进程多线程的目的都是想尽可能的利用CPU,减少CPU的空闲时间,特别是多核环境,今天咱不做深度解读,跳过...0x01线程池锁最早的一部分游戏服务器是采用线程池的方式来处理玩家的业务请求,以达最大限度的利用多核优势来提高处理业务能力。但线程池同时也带来了并发问题,为了解决同一玩家多个业务请求不被
Wesley13 Wesley13
2年前
F28379D烧写双核程序(在线&离线)
烧写双核程序前需知在分别对F28379D的CPU1和CPU2两个核进行烧写程序时,需要在CCS中建立两个工程,独立编写两个核的程序。如controlSUITE中提供的双核程序例程:1\.在线1.1编译烧写CPU1程序到F28379D中1.2编译CPU2程序,把生成的.out文件加载到CPU2中选中上图中红色框框中的
Wesley13 Wesley13
2年前
CPU,并行,并发,多线程
1.CPUI5处理器有四核四线程和四核八线程两种:(1).四核四线程:就是CPU有四个物理核心,每个核心一个时间内只处理一个线程调度,任务管理器中只显示4个CPU图表;(2)四核八线程:使用了超线程技术,把一个物理核心,模拟成两个逻辑核心,任务管理器中会显示8个CPU图表;I7处理器的八核八线程:有八个物理核心可以
一种动态实现核隔离的方法
一种动态实现核隔离的方法相关概念:核隔离:指定的cpu核心只参与最低限度的OS内核计算; DPDK(Dateplanedevelopmentkit):是一个用来进行包数据处理加速的软件库。Cpu亲和性:进程要在某个给定的CPU上尽量长时间地运行而不被迁移到其他处理器的倾向性。