电子工程专辑互动社区>自由讨论>嵌入式系统专区>高性能多核网络软件设计选项
作者 问题:

高性能多核网络软件设计选项

发布时间:2012-9-1 下午6:11

作者: woyeah

等级: 初入江湖

积分: 94分

发帖数: 2次

网站总积分: 95分

经验值: 0.0

查看用户的所有发言

查看用户的个人e空间

需要确认注册邮箱后才能下载,立即确认我的邮箱
回复后可下载附件 关闭
概述
随着 CPU 核心数量的增加,传统的对称多处理系统的扩展性相对受到限制,因共享内
存争用和多核调度造成的瓶颈问题变得愈发突出。这就出现了包处理性能的平整化,
即随着内核数量的增加,性能只有微小的改进,在一些情况下甚至还会出现性能的下
降。
如果设备提供商是出于简单和方便的原因而准备将自己的设计建立在传统的SMP 上,
那么在开始之前,他们应当先了解这种方式可能存在的缺点。当从四核系统移植到八
核或更多核的时,性能的提升并不一定等同从单核移植到双核或四核系统的效果。
本文探讨了一些不同的多核网络软件设计选项,这些选项要比传统的SMP 具有更好
的扩展性。设备提供商可以通过这些选项实现面向未来的设计,使用一个通用的架构
就能满足当前的性能要求和未来的扩展需要。
本文首先对典型的设计选项进行了概览,然后对传统Linux SMP 进行了简要总结,接
着将探讨英特尔数据面开发工具套件(DPDK)的使用和风河公司的多核非对称多处
理(AMP)产品 – 风河网络加速平台。与仅使用Linux SMP 的方式相比,这些选项
均提供了更好的性能和扩展性。
多核网络软件设计选项
一般来说,当设计多核网络平台时,系统架构师只能选择商业现货的对称多处理
(SMP)操作系统或使用非对称多处理(AMP)重新进行设计。SMP 是一种共享架
构,所有的内核都运行一个操作系统实例,并共享所有的数据。AMP 是一种分区架构,
不同的内核运行不同的操作系统或者是同一个操作系统多个独立的实例。
如果设计合理,那么如今的应用程序可以不太费力地移植到通用的对称多处理操作系
统架构中。操作系统可以决定在何时、何地来调度应用程序线程,以及如何将线程无
缝地从一个核移植到另一个核。经过精细调整后,这些应用程序一般都可以实现很好
的性能,但是缺乏扩展性则是一个问题。随着核心数量和线程的增加,共享数据结构
中出现互锁的频率也会增加,再加上其他性能瓶颈,从而造成共享内存模式的崩溃。
另一方面,非对称多处理的系统则往往是按照特定用途建造的,其架构在很大程度上
取决于应用程序本身的需求。在网络方面,AMP 的架构往往包含一个核或少数几个核
上的单个管理面实例,以及在其余核上的多个独立的专门用途数据面实例。要将一个
应用程序从通用操作系统移植到专门用途的AMP 平台,不仅需要将应用程序的数据
面和管理面分离,而且可能还需要“自己手工配置”底层库的实现以及类似于内核的数
据面服务。这些额外的工作可以带来更高的性能,而且如果软件针对运行的硬件架构
进行了优化,那么性能提升的效果将更加明显。
传统的LINUX SMP
计算行业内的人士都很清楚,要充分利用多核能力,软
件必须是多线程的;执行的序列必须不止一个,这样内
核才能同时运行不同的线程。换句话说,软件能够并发
执行自己的工作,这对于提高多核性能至关重要。如今
很多应用程序都利用了这一概念,并获得了令人印象深
刻的结果。
类似的,Linux 也取得了很多进展以利用多核处理器的优
势。调度程序效率的改善和线程亲和性,以及避免粗粒
度的内核锁定,这些都有助于提高性能。虽然毫无疑问
这方面的改进还将继续,但是随着内核数量的增加,共
享内存争用和核心间调度成为严重影响性能的因素。单
独的网络堆栈实例具有多个线程,但是却共享数据,这
也一直是传统SMP 系统中的一个瓶颈。其他限制性能的
因素还包括旁路转换缓冲区(TLB)击不中概率的增加
以及受限的页面大小。
此外,在很多网络应用程序中,数据在系统中的进出是
性能上的瓶颈。数据路径应当精简,从而尽快地将数据
包在网络接口卡(NIC)和用户空间应用程序之间移动。
较新的处理器架构有着更高的总线效率、较大的高速缓
存、更快的内存、并且采用了对称多处理,这些都有助
于提高数据移动效率并减少CPU 停滞。Linux 也在网络
输入/输出(I/O)的处理方面进行了改进,不过精简数据
路径的单一关注点与通用操作系统的任务有所冲突,因
为操作系统必须在各方面进行平衡。
所以,尽管Linux 和Linux 应用程序最近取得了一些进展,
但是Linux SMP 最突出的贡献是使应用程序能够利用操
作系统实现多核支持,方便地启动和运行,并且在小型
的SMP 系统中取得相应和适当的性能提升。
?
英特尔数据面开发工具套件
英特尔数据面开发工具套件(Intel DPDK)是一套专门
针对高速网络而设计的数据面库。它与英特尔架构(IA)
产品家族中的所有处理器兼容,提供了一个可以用于从
英特尔凌动(Atom)到最新的英特尔至强(Xeon)处理
器的统一软件编程模式,适用于大量不同的网络应用程
序和系统配置。
Intel DPDK 提供了一套可以从Linux 用户空间使用的
API,从而提供了一个低开销的方法来替代传统的Linux
系统调用。与原始Linux 程序相比,通过这种方式创建
的专门用途用户空间应用程序具有更好的性能扩展性。
这些库针对英特尔处理器进行了优化,包括用于特定硬
件初始化和配置的环境抽象层(EAL)、用于缓冲区分配
和解除分配的缓冲区管理、使用无锁环以提高弹性并避
免通信任务间延迟的环管理、用于数据包和数据流查看
和分类的流分类、以及采用轮询、无中断机制从网络接
口卡接收数据帧的轮询模式驱动程序(PMD)和其他大
量的实用工具,例如定时器、日志以及调试功能(图1)。
Intel DPDK 用户空间库和Linux
Linux 和Intel DPDK 应用程序位于用户空间中,并使用
数据面库来接收和发送数据包,在进行常规数据面处理
时绕过了Linux 内核。Linux 内核对Intel DPDK 应用程
序的处理和其他用户空间应用程序一样;它的编译、链
接和载入都是以常规方式进行的。该应用程序作为一个
单一的Linux 进程启动,使用Pthread 线程实现并发处
理,并通过Pthread 亲和性将每个线程附着到指定的内
核。
为了理解采用Intel DPDK 方式带来的好处,我们可以回
顾一下传统的Linux 是如何处理网络流量,以及用户应
用程序一般是如何与Linux 内核交互的。Linux 等通用操
作系统在处理各种应用程序时不带任何偏见。操作系统
必须能够在各方利益间进行平衡,并提供足够的安全机
制来防止应用程序相互干扰或对内核造成影响。这些安
全机制包括明确地划分应用程序和内核之间的界限,并
设置一套规则来管理它们之间的交互作用。虽然Linux
的内核及其处理网络流量的方式有了很多改进,但是它
毕竟还是一个通用操作系统,有着这种操作系统内在的
优势和缺点。
另一方面,Intel DPDK 则是针对专门用途的数据I/O 密
集型网络应用程序而设计。这些库可以帮助应用程序有
效地接收和发送数据,并为更复杂网络软件的开发提供
基础构件。这种方式使软件开发人员可以关注于应用程
序本身,而不必花费精力来确定如何配置和精细调节操
作系统以提高性能。与此同时,虽然这些库的应用是针
对英特尔架构进行优化的,但是Intel DPDK 并没有引入
或向应用程序强加任何特别的硬件范式。相反,可以将
Intel DPDK 视为一个工具包,应用程序开发人员可以利
用它来提取、提供实时软件开发人员所熟悉的性能增强
技术优化实现,例如轮询或使用无锁环和零拷贝缓冲,
所有这些都可以在用户空间中提供,同时避免了内核的
常见问题。
在典型的网络场景下,数据包将由网络接口卡接收,然
后进行分类并生成规定的动作,并对数据包付诸实施。
无论应用程序是路由器、防火墙、还是内容感知的应用
程序(例如应用程序代理),如何在接收到流量时进行快
速处理都是首要的问题。目前几个G 的网速已经非常普
遍,因此我们必须认识到,即使是在1G 以太网连接中,
用于处理数据包的时间也只有短短的672 纳秒(对于
2.4GHz 处理器来说为1613 个CPU 周期),这对于任何
通用操作系统都是一个挑战。虽然性能可能取决于多种
因素,不过最近对英特尔平台上的本地新型Linux 堆栈
的测量表明,小型数据包的转发速度大约为1Mpps/核
心,或者是667Mbps。要实现更高的合计线路速度,或
者为了以线路速度支持更加高级的应用,需要采取不同
的方式。
在传统的Linux 模式下,系统接收数据包和将数据包发
送出系统的过程占了包处理中很大一部分时间,这可能
会出乎有些人的预料。换句话说,即使用户空间应用程
序什么都不做,而只是将数据包从接收端口传送到发送
端口,那么仍然会花费大量的处理时间。为了展示与运
行Linux 应用程序相关的基线成本,请考虑一下当用户
空间应用程序接收和发送数据帧时会发生什么情况(图
2)。
当网卡从网络接收到一个数据帧后,会使用直接内存访
问(DMA)将数据帧传送到针对这一目的而预先分配的
内核缓冲区内,更新适当的接收描述符环,然后发出中
断通知数据帧的到达。操作系统对中断进行处理,更新
环,然后将数据帧交给网络堆栈。网络堆栈对数据进行
处理,如果数据帧的目的地是本地套接字,那么就将数
据复制到该套接字,而拥有该套接字的用户空间应用程
序就接收到了这些数据。
进行传输时,用户应用程序通过系统调用将数据写入到
一个套接字,使Linux 内核将数据从用户缓冲区复制到
内核缓冲区中。然后网络堆栈对数据进行处理,并根据
需要对其进行封装,然后再调用网卡驱动程序。网卡驱
动程序会更新适当的传输描述符环,并通知网卡有一个
等待处理的传输任务。网卡将数据帧从内核缓冲区转移
到自己内置的先进先出(FIFO)缓冲区,然后将数据帧
传输到网络。接着网卡会发出一个中断,通知数据帧已
经成功传输,从而使内核释放与该数据帧相关的缓冲区。
虽然这只是一个极其简单的描述,但是仍然突出说明了
处理过程中一些不属于应用程序处理的部分,而这些工
作可以被视为间接开销(至少从应用程序的角度来说是
这样)。
??中断处理:这包括在接收到中断时暂停正在执行的任
务,对中断进行处理,并调度softIRQ 处理程序来执
行中断调用的实际工作。随着网络流量负荷的增加,
系统将会花费越来越多的时间来处理中断,当流量速
度达到10G 以太网卡的线路速度时就会严重影响性
能。而对于有着多个10G 以太网卡的情况,那么系
统可以会被中断淹没,对所有的服务产生负面影响。
??上下文切换:上下文切换指的是将来自当前执行线程
的寄存器和状态信息加以保存,之后再将来自被抢占
线程的寄存器和状态信息加以恢复,使该线程能够从
原先中断的地方重新开始执行。调度和中断都会引发
上下文切换。
??系统调用:系统调用会造成用户模式切换到内核模
式,然后再切换回用户模式。这会造成管道冲刷并污
染高速缓存。
??数据复制:数据帧会从内核缓冲区复制到用户套接
字,并从用户套接字复制到内核缓冲区。执行这一操
作的时间取决于复制的数据量。
??调度:调度程序使每个线程都能运行很短的一段时
间,造成多任务内核中并发执行的假象。当发生调度
定时器中断或在其他一些检查时间点上,Linux 调度
程序就会运行,以检查当前线程是否时间已到。当调
度程序决定应该运行另一个线程时,就会发生上下文
切换。
虽然其中一些开销可以分摊到多个到达的数据帧上,不
过大体上,其成本很容易就能达到数百个CPU 周期/帧,
这造成的区别就是仅能以线速度的很小一部分进行处
理,而不是以完全的线速度进行处理。
为了解决这些问题,Intel DPDK 为部署的应用程序和网
络堆栈提供了一个框架,可以直接与硬件工作来处理网
络流量,从而减少中断、上下文切换和数据复制操作。
应用程序和网络堆栈位于用户空间内,并且调用Intel
DPDK 库来提供数据面功能(包括将接收到的数据包转
发给Linux 进行异常处理)而不是向Linux 内核提出系统
调用。Intel DPDK API 使应用程序在初始化的时候留出
内存,包括缓冲池、描述符环和无锁队列。
通过在一开始就分配缓冲区,应用程序就可以避免在常
规数据面处理的时候向Linux 内核请求缓冲区以及相关
的开销。从Linux 内核的角度来看,Intel DPDK 应用程
序拥有那块内存,因此内核并不关心该内存以后是如何
使用的。在正常的操作中,应用程序根据需要调用相应
的Intel DPDK API,从这一内存中分配和取消分配缓冲
区。再加上Intel DPDK 启用的网卡驱动程序,数据帧就
可以在接收时被直接放置到应用程序缓冲区中,并且在
发送时直接从应用程序缓冲区中获取,而无需内核的干
预,从而提供了一个零拷贝的数据面环境。这样的实际
效果就是,Intel DPDK 使数据面的处理能够绕过Linux
内核(图3)。
在概念上,Intel DPDK 应用程序拥有自己的运行时环境
(RTE),而运行时环境在Linux 上方在每个Intel DPDK
核心上工作。对于每个Intel DPDK 核心,运行时环境都
提供了一个低开销、紧凑型的环境,应用程序可以在这
一环境中执行,并包含一个“运行直到完成”的调度回
路,该回路在应用程序需要在该核心上执行的所有工作
之间循环。
该回路的一个功能就是持续地检查网卡有没有接收到数
据帧,从而消除了处理网络活动中断而引起的开销。调
度回路的组成部分,包括每个任务的服务频率,都完全
取决于应用程序(图4)。
图 4:调度回路示例
在这个简单的例子中,创建了多个任务来处理网络流量。
需要注意的是,在这一场景中,一个任务仅仅指的是执
行特定功能的一小块工作,而不是指的操作系统任务。
轮询模式驱动程序检测到数据帧,并将其转交给流量分
类任务进行分类。基于查看结果,数据帧可能被转发、
丢弃、转交给IPsec、传递给Linux、或者被发送进行端
点处理。每个任务的输入通过进入一个多生产者、单消
费者的无锁队列来实现,提供任务间的异步耦合。
图3:
现在,当网卡接收到来自网络的数据帧时,会将该数据
帧移动到针对这一目的而预先分配的用户空间缓冲区,
并更新适当的接收描述符环。应用程序通过轮询的方式
检测到新数据帧的到达,然后开始对数据帧进行处理。
在这一过程中没有拷贝操作。
进行传输时,用户应用程序会在用户空间缓冲区内构建
数据帧,更新传输描述符环,并通知网卡有等待处理的
传输。网卡将数据帧直接从用户空间移动到自己内置的
先进先出缓冲区,然后将数据帧发送到网络。应用程序
对网卡进行轮询,从而检测到传输完成,并释放与该数
据帧关联的缓冲区。
Intel DPDK 和Linux SMP
在这一模型中,主核上的Intel DPDK 应用程序保留并初
始化与高速缓存相应的内存、检测设备、设置超大页面、
并生成其他核上的应用程序线程。线程被成功地创建和
初始化后,主核将设置设备和核心间的映射,包括在适
当的情况下使用无锁队列。为了避免缓冲区争用,每个
线程都有自己的缓冲池高速缓存,并根据需要进行补充。
Linux 处理各个核上应用程序线程调度的所有方面,但是
为了实现最佳的性能,每个应用程序线程都应当被锁定
到特定的硬件线程。Intel DPDK 通过Pthread 亲和性来
实现这一点(图5)。
在六核 2.4 GHz 英特尔至强处理器E5645 上以这种模式
运行Intel DPDK 时,对于使用六个核中的四个核、每个
核一个线程、四个10G 以太网端口的情况,使用流分类
的64 字节数据包的IP 第三层转发性能达到了
35.2Mpps。
当在六核 2.0 GHz 英特尔至强处理器L5638 上使用最长
前缀匹配(LPM)时,对于使用六个核心中的四个核心、
每个核一个线程、四个10G 以太网端口的情况,64 字
节数据包的IP 第三层转发性能达到了41.1Mpps。这比
原始Linux 的性能差不多提高了十倍(原始Linux 在双
处理器六核2.4GHz 模式下的性能为12.2Mpps)。
图5:
?
这种方式是针对开发了自己网络堆栈并希望在多核平台
上快速展示主路径性能的客户而定制的。如果堆栈还不
是单线程的,那么可能会需要一些额外的工作使堆栈适
应到Intel DPDK 单线程环境。如果对英特尔架构和优化
有着深入的了解,就有助于客户将自己的软件移植到最
新的英特尔处理器和硬件目标机上,从而能够从高速发
展的处理器路线图中受益。
虽然 Linux 系统解决了很多基础设施问题,例如引导、使
用共享内存、以及在SMP 中进行调度,但是还有一些基
础的设计问题需要考虑。数据面与Linux 的分离取得了更
好的数据面性能,但是需要定义和解决数据面的管理问
题。例如,路由更新是在哪里进行处理的,以及转发表
是如何变化的?Linux 和数据面之间的互动是怎样的,以
及异常路径处理是如何处理的?Linux 是否看管数据面
接口,或者Linux 是否管理自己的一套接口?
由于这种方式采用了开放式的管理面设计,因此客户能
够实施自己专有的管理方案。
?
?
?
?
?
?
???标签: 设计
引用 回复 鲜花 ( 0) 臭鸡蛋 ( 0) 有新回复时发送邮件通知
上一帖????altium Designe...
多核挑战与机遇-????下一帖??

与?设计?相关的话题
?
快速回复
用户名:?
美国的游客?????? (您将以游客身份发表,请登陆 | 注册 ) ?
标题: * 你还可以输入80
评论: * 你还可以输入10000
分享到: 新浪微博?? qq空间?? qq微博?? 人人网?? 百度搜藏??
验证码: ?*?
维护专业、整洁的论坛环境需要您的参与,请及时举报违规帖子,如果举报属实,我们将给予相应的积分奖励。
谢谢您的热心参与!
返回嵌入式系统专区 | 返回自由讨论
本论坛仅陈述专家或个人观点,并不代表电子工程专辑网站立场。
返回论坛页首
有问题请反馈