DPDK(Data Plane Development Kit)是由6WIND,Intel等多家公司开发,主要基于Linux系统运行,用于快速数据包处理的函数库与驱动集合,可以极大提高数据处理性能和吞吐量,提高数据平面应用程序的工作效率。
DPDK使用了轮询(polling)而不是中断来处理数据包。在收到数据包时,经DPDK重载的网卡驱动不会通过中断通知CPU,而是直接将数据包存入内存,交付应用层软件通过DPDK提供的接口来直接处理,这样节省了大量的CPU中断时间和内存拷贝时间。
Why need DPDK
Where are the bottlenecks?
=> System calls 系统调用把应用程序的请求传给内核,调用相应的内核函数完成所需的处理,将处理结果返回给应用程序
=> interrupt processing
=> switching between user space and kernel space => data copy 用户平面到内核平面数据复制
=> Scheduling and content switch of user processes 用户进程的调度和内容切换
=> Inefficient read/write of memory, cache miss 不够有效的内存读写,很多cache miss, Cache是用来对内存数据的缓存。CPU要访问的数据在Cache中有缓存,称为“命中” (Hit),反之则称为“缺失” (Miss)。
=> Lock/unlock involved in shared data structure access 共享结构体需要锁操作
Where are the bottlenecks?
=> System calls 系统调用把应用程序的请求传给内核,调用相应的内核函数完成所需的处理,将处理结果返回给应用程序
=> interrupt processing
=> switching between user space and kernel space => data copy 用户平面到内核平面数据复制
=> Scheduling and content switch of user processes 用户进程的调度和内容切换
=> Inefficient read/write of memory, cache miss 不够有效的内存读写,很多cache miss, Cache是用来对内存数据的缓存。CPU要访问的数据在Cache中有缓存,称为“命中” (Hit),反之则称为“缺失” (Miss)。
=> Lock/unlock involved in shared data structure access 共享结构体需要锁操作
以上几条都会耗费很多clock cycle, 对于实时系统来说,不能容忍。
How to deal with the problems?
=> Use polled mode driver (PMD) instead of interrupted driven network device driver
=> Access to device from user space instead of kernel space 直接从用户空间访问外设
=> Optimized memory access between PCIe device to cache 优化内存访问
==> Huge pages
==> Batch packet processing
==> HW/SW control prefethcing, Data Direct IO
==> Data alignment
=> Use lockless queue to optimized shared data structure 用无锁队列来优化共享结构体
=> Bind a single software thread to a logical core
=> Use polled mode driver (PMD) instead of interrupted driven network device driver
=> Access to device from user space instead of kernel space 直接从用户空间访问外设
=> Optimized memory access between PCIe device to cache 优化内存访问
==> Huge pages
==> Batch packet processing
==> HW/SW control prefethcing, Data Direct IO
==> Data alignment
=> Use lockless queue to optimized shared data structure 用无锁队列来优化共享结构体
=> Bind a single software thread to a logical core
What we need to do?
=> Need to unload the Kernel NIC driver and switch to pool mode driver => dpdk setup 在初始化的时候,把正常的Network interface controller(NIC)
=> Need to set huge page memory => dpdk setup 初始化的时候,设置huge page (grep HugePages /proc/meminfo):系统进程是通过虚拟地址访问内存,但是CPU必须把它转换程物理内存地址才能真正访问内存。为了提高这个转换效率,CPU会缓存最近的虚拟内存地址和物理内存地址的映射关系,并保存在一个由CPU维护的映射表中。为了尽量提高内存的访问速度,需要在映射表中保存尽量多的映射关系。而在Linux中,内存都是以页的形式划分的,默认情况下每页是4K,这就意味着如果物理内存很大,则映射表的条目将会非常多,会影响CPU的检索效率。因为内存大小是固定的,为了减少映射表的条目,可采取的办法只有增加页的尺寸。
=> Bind software thread to logical cores => CpuInfo.dat
=> Need to unload the Kernel NIC driver and switch to pool mode driver => dpdk setup 在初始化的时候,把正常的Network interface controller(NIC)
=> Need to set huge page memory => dpdk setup 初始化的时候,设置huge page (grep HugePages /proc/meminfo):系统进程是通过虚拟地址访问内存,但是CPU必须把它转换程物理内存地址才能真正访问内存。为了提高这个转换效率,CPU会缓存最近的虚拟内存地址和物理内存地址的映射关系,并保存在一个由CPU维护的映射表中。为了尽量提高内存的访问速度,需要在映射表中保存尽量多的映射关系。而在Linux中,内存都是以页的形式划分的,默认情况下每页是4K,这就意味着如果物理内存很大,则映射表的条目将会非常多,会影响CPU的检索效率。因为内存大小是固定的,为了减少映射表的条目,可采取的办法只有增加页的尺寸。
=> Bind software thread to logical cores => CpuInfo.dat
聪明不聪明,不在于脑袋的灵活度,而在于你的贡献。脚踏实地,做一番事业,做一个聪明的人