dpdk和linux内核中断区别,DPDK解析-----DPDK,PF_RING对比

DPDK(Data Plane Development Kit)是数据平面开发工具包,由用于加速在各种CPU架构上运行的数据包处理的库组成。

在Linux上捕获数据包有多种方式,常见的有libpcap,pf-ring等。DPDK以高性能著称,想必相比传统的数据包捕获方式,一定有其独到之处。

本文主要就DPDK所使用的技术点进行宏观的说明,并将其与libpcap,pf-ring进行对比,若有写的不对的地方请帮忙指出。

若出现侵权请联系作者删除。

1.DPDK 技术特点

传统的数据包捕获瓶颈往往在于Linux Kernel,数据流需要经过Linux Kernel,就会带来Kernel Spcae和User Space数据拷贝的消耗;系统调用的消耗;中断处理的消耗等。

DPDK针对Linux Kernel传统的数据包捕获模式的问题,进行了一定程度的优化。DPDK的优化可以概括为:

UIO+mmap 实现零拷贝(zero copy)

UIO+PMD 减少中断和CPU上下文切换

HugePages 减少TLB miss

其他代码优化

2.UIO

2.1 UIO简介

UIO(Userspace I/O)是运行在用户空间的I/O技术。Linux系统中一般的驱动设备都是运行在内核空间,而在用户空间用应用程序调用即可,而UIO则是将驱动的很少一部分运行在内核空间,而在用户空间实现驱动的绝大多数功能。

9b669f7c97ce

图片引自百度百科

一个设备驱动的主要任务有两个:

存取设备的内存

处理设备产生的中断

如上图所示,对于存取设备的内存 ,UIO 核心实现了mmap();对于处理设备产生的中断,内核空间有一小部分代码用处理中断,用户空间通过read()接口/dev/uioX来读取中断。

2.2 DPDK UIO机制

采用Linux提供UIO机制,可以旁路Kernel,将所有报文处理的工作在用户空间完成。

9b669f7c97ce

图片引自参考文档[1]

如上图,左边是传统的数据包获取方式,路径为:

网卡 -> Kernel驱动 -> Kernel TCP/IP协议栈 -> Socket接口 -> 业务

右边是DPDK的方式,基于UIO。数据路径为:

网卡 -> DPDK轮询模式-> DPDK基础库 -> 业务

2.3 DPDK 零拷贝(Zero Copy)

通过UIO+mmap 实现数据零拷贝(zero copy)是DPDK的特点之一。那么常规的Linux Kernel(libpcap)以及pf-ring处理数据包的流程要进行几次数据拷贝呢?

libpcap

libpcap采用的是传统的数据包获取方式,如上图左边路径。

网卡接收到数据包后,第一步需要把数据从网卡拷贝到主存(RX buffer)中。但是在这个拷贝的过程中使用了DMA(Direct Memory Access)技术。DMA 传输将数据从一个地址空间复制到另外一个地址空间。由CPU 初始化这个传输动作,传输动作本身是由 DMA 控制器来实行和完成,CPU是不需要参与,也不会产生CPU资源消耗。因此这个第一步的拷贝可以忽略。

第二步,Kernel会将网卡通过DMA传输进入主存(RX buffer)的内容拷贝一份进行处理,这里进行了一次数据拷贝。

第三步,由于内核空间和用户空间的内存是不共享的,Kernel会将数据包内容再进行一次拷贝用于用户空间使用。

综上,传统的数据包捕获方式(libpcap)会进行两次数据包拷贝。

pf-rfing

pf-ring采用mmap()将传统的两次拷贝减少至一次拷贝。

第一步,同样使用DMA技术,把数据从网卡拷贝到主存(RX buffer)中。

第二步,pf-ring会将网卡通过DMA传输进入主存(RX buffer)的内容拷贝一份放入环形缓冲区中(ring)中,这里进行了一次数据拷贝。

第三步,使用mmap()将环形缓冲区映射至用户空间,用户空间可以直接访问这个环形缓冲区中的数据。

pf-ring zc

pf-ring zc(zero copy)更是将pf-ring的一次拷贝也省去,达到了零拷贝的目的,具体的:

第一步,使用DMA技术,把数据从网卡拷贝到主存(RX buffer)中。

第二步,使用mmap()直接将RX buffer的数据映射到用户用户空间,使用户空间可以直接访问RX buffer的数据。

下图非常清晰地展示了pf-ring zc实现零拷贝的过程:

9b669f7c97ce

图片引自参考文档[3]

DPDK

DPDK实现零拷贝的方式与pf-ring zc类似,首先通过DMA将网卡数据拷贝至主存(RX buffer);随后使用mmap()直接将RX buffer的数据映射到用户用户空间,使用户空间可以直接访问RX buffer的数据,以此实现了零拷贝。

由上述可以看出,pf-ring zc和dpdk均可以实现数据包的零拷贝,两者均旁路了内核,但是实现原理略有不同。pf-ring zc通过zc驱动(也在应用层)接管数据包,dpdk基于UIO实现。

值得注意的是,无论是pf-ring zc还是dpdk,旁路内核就意味着应用程序完全接管网卡,这样一来,当通过UIO驱动或ZC驱动打开设备时,设备将无法用于标准网络。

3.PMD

DPDK的UIO驱动屏蔽了硬件发出中断,然后在用户态采用主动轮询的方式,这种模式被称为PMD(Poll Mode Driver)。

正常情况下,网卡收到数据包后,会发出中断信号,CPU接收到中断信号后,会停止正在运行的程序,保护断点地址和处理机当前状态,转入相应的中断服务程序并执行中断服务程序,完成后,继续执行中断前的程序。

DPDK采用轮询的方式,直接访问RX和TX描述符而没有任何中断,以便在用户的应用程序中快速接收,处理和传送数据包。这样可以减少CPU频繁中断,切换上下文带来的消耗。

在网卡大流量时,DPDK这种PMD的方式会带来较大的性能提升;但是在流量小的时候,轮询会导致CPU空转(不断轮询),从而导致CPU性能浪费和功耗问题。

为此,DPDK还推出了Interrupt DPDK模式,它的原理和Linux的NAPI很像,就是没包可处理时进入睡眠,改为中断通知。并且可以和其他进程共享同个CPU Core,但是DPDK进程会有更高调度优先级。

与DPDK相比,pf-ring(no zc)使用的是NAPI polling和应用层polling,而pf-ring zc与DPDK类似,仅使用应用层polling。

9b669f7c97ce

图片引自官网

4.HugePages

Linux系统默认采用4KB作为页的大小(page size),页的大小越小,设备的内存越大,页面的个数就越多,页表的开销就越大,页表的内存占用也越大。

在操作系统引入MMU(Memory Management Unit)后,CPU读取内存的数据需要两次访问内存。第一次要查询页表将逻辑地址转换为物理地址,然后访问该物理地址读取数据或指令。

为了减少页数过多,页表过大而导致的查询时间过长的问题,便引入了TLB(Translation Lookaside Buffer),可翻译为地址转换缓冲器。TLB是一个内存管理单元,一般存储在寄存器中,里面存储了当前最可能被访问到的一小部分页表项。

引入TLB后,CPU会首先去TLB中寻址,由于TLB存放在寄存器中,且其只包含一小部分页表项,因此查询速度非常快。若TLB中寻址成功(TLB hit),则无需再去RAM中查询页表;若TLB中寻址失败(TLB miss),则需要去RAM中查询页表,查询到后,会将该页更新至TLB中。

而DPDK采用HugePages ,在x86-64下支持2MB、1GB的页大小,大大降低了总页个数和页表的大小,从而大大降低TLB miss的几率,提升CPU寻址性能。

5. 其他代码优化

目前对DPDK的代码研究还不是很深入,这里摘录自参考文档1。

SNA(Shared-nothing Architecture)

软件架构去中心化,尽量避免全局共享,带来全局竞争,失去横向扩展的能力。NUMA体系下不跨Node远程使用内存。

SIMD(Single Instruction Multiple Data)

从最早的mmx/sse到最新的avx2,SIMD的能力一直在增强。DPDK采用批量同时处理多个包,再用向量编程,一个周期内对所有包进行处理。比如,memcpy就使用SIMD来提高速度。

SIMD在游戏后台比较常见,但是其他业务如果有类似批量处理的场景,要提高性能,也可看看能否满足。

不使用慢速API

cpu affinity

编译执行优化

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值