DPDK学习开篇

1.前言面试

说来想学习DPDK已是好久的事情了,奈何老是被所谓的紧急的事情耽误,故而决心学习一下,记录一下以便总结,知道DPDK已是好久以前的事情了,记得曾经一次面试就被问到DPDK报文如何走的,也是被问的一脸懵逼甚是尴尬, 主要是工做中用到会比较多, 我的对DPDK的处理机制也是很感兴趣编程

2.DPDK介绍网络

Intel® DPDK 全称 __Intel Data Plane Development Kit__,是intel提供的数据平面开发工具集,为Intel architecture(IA)处理器架构下用户空间高效的数据包处理提供库函数和驱动的支持,它不一样于Linux系统以通用性设计为目的,而是专一于网络应用中数据包的高性能处理。其工做在用户层,取代传统Linux系统中的网络数据报文处理。但须要注意的是,DPDK提供的是高性能处理报文的能力,而不是对报文的处理。这也提供了咱们自定义用户协议栈的能力数据结构

3.DPDK 优点多线程

1)轮询与中断架构

起初的纯轮询模式是指收发包彻底不使用任何中断,集中全部运算资源用于报文处理。DPDK纯轮询模式是指收发包彻底不使用中断处理的高吞吐率的方 式。DPDK全部的收发包有关的中断在物理端口初始化的时候都会关 闭,也就是说,CPU这边在任什么时候候都不会收到收包或者发包成功的中 断信号,也不须要任何收发包有关的中断处理。具体收发包流程参见以后的文章单独说明。网络应用中可能存在的潮汐效应,在某些时间段网络数据 流量可能很低,甚至彻底没有须要处理的包,这样就会出如今高速端口 下低负荷运行的场景,而彻底轮询的方式会让处理器一直全速运行,明 显浪费处理能力和不节能。所以在DPDK R2.1和R2.2陆续添加了收包中 断与轮询的混合模式的支持,相似NAPI的思路,用户能够根据实际应 用场景来选择彻底轮询模式,或者混合中断轮询模式。并且,彻底由用 户来制定中断和轮询的切换策略,好比何时开始进入中断休眠等待 收包,中断唤醒后轮询多长时间,等等。负载均衡

2)多线程编程:
多线程编程早已不是什么新鲜的事物了,多线程的初衷是提升总体应用程序的性能,可是若是不加注意,就会将多线程的建立和销毁开销,锁竞争,访存冲突,cache失效,上下文切换等诸多消耗性能的因素引入进来。为了进一步提升性能,就必须仔细斟酌考虑线程在CPU不一样核上的分布状况,这也就是常说的多核编程。多核编程和多线程有很大的不一样:多线程是指每一个CPU上能够运行多个线程,涉及到线程调度、锁机制以及上下文的切换;而多核则是每一个CPU核一个线程,核心之间访问数据无需上锁。为了最大限度减小线程调度的资源消耗,须要将Linux绑定在特定的核上,释放其他核心来专供应用程序使用。DPDK的线程基于pthread接口建立,属于抢占式线程模型,受内核 调度支配。DPDK经过在多核设备上建立多个线程,每一个线程绑定到单 独的核上,减小线程调度的开销,以提升性能。DPDK的线程能够做为控制线程,也能够做为数据线程。在DPDK 的一些示例中,控制线程通常绑定到MASTER核上,接受用户配置,并 传递配置参数给数据线程等;数据线程分布在不一样核上处理数据包。同时还须要考虑CPU特性和系统是否支持NUMA架构,若是支持的话,不一样插槽上CPU的进程要避免访问远端内存,尽可能访问本端内存。ide

3)CPU亲核性:
当处理器进入多核架构后,天然会面对一个问题,按照什么策略将 任务线程分配到各个处理器上执行。众所周知的是,这个分配工做通常 由操做系统完成。负载均衡固然是比较理想的策略,按需指定的方式也 是很天然的诉求,由于其具备肯定性。简单地说,CPU亲和性(Core affinity)就是一个特定的任务要在某 个给定的CPU上尽可能长时间地运行而不被迁移到其余处理器上的倾向 性。这意味着线程能够不在处理器之间频繁迁移。这种状态正是咱们所 但愿的,由于线程迁移的频率小就意味着产生的负载小。将线程与CPU绑定,最直观的好处就是提升了CPU Cache的命中 率,从而减小内存访问损耗,提升程序的速度。在Linux内核中,全部的线程都有一个相关的数据结构,称为 task_struct。这个结构很是重要,缘由有不少;其中与亲和性相关度最 高的是cpus_allowed位掩码。这个位掩码由n位组成,与系统中的n个逻 辑处理器一一对应。具备4个物理CPU的系统能够有4位。若是这些CPU 都启用了超线程,那么这个系统就有一个8位的位掩码。若是针对某个线程设置了指定的位,那么这个线程就能够在相关的 CPU上运行。所以,若是一个线程能够在任何CPU上运行,而且可以根 据须要在处理器之间进行迁移,那么位掩码就全是1。实际上,在Linux 中,这就是线程的默认状态。DPDK经过把线程绑定到逻辑核的方法来避免跨核任务中的切换开 销,但对于绑定运行的当前逻辑核,仍然可能会有线程切换的发生,若 但愿进一步减小其余任务对于某个特定任务的影响,在亲和的基础上更 进一步,能够采起把逻辑核从内核调度系统剥离的方法。函数

4)大页表:
默认下Linux采用4KB为一页,页越小内存越大,页表的开销越大,页表的内存占用也越大。CPU有TLB(Translation Lookaside Buffer)成本高因此通常就只能存放几百到上千个页表项。若是进程要使用64G内存,则64G/4KB=16000000(一千六百万)页,每页在页表项中占用16000000 * 4B=62MB。若是用HugePage采用2MB做为一页,只需64G/2MB=2000,数量不在同个级别。而DPDK采用HugePage,在x86-64下支持2MB、1GB的页大小,几何级的下降了页表项的大小,从而减小TLB-Miss。工具

5)无锁机制:

实际上DPDK内部也有读写锁,LINUX系统自己也支持无锁操做,而且DPDK内部的无锁机制实现原理同LINUX系统提供的无锁机制的实现原理相似。二者都采用无锁环形队列的方式,采用环形队列的好处是,当一个数据元素被用掉后,其他数据元素不须要移动其存储位置,从而减小拷贝,提升效率。LINUX系统若是仅仅有一个读用户和一个写用户,那么不须要添加互斥保护机制就能够 保证数据的正确性。可是,若是有多个读写用户访问环形缓冲区,那么 必须添加互斥保护机制来确保多个用户互斥访问环形缓冲区。DPDK的无锁环形队列不管是单用户读写仍是多用户读写都不须要使用互斥锁保护。

5)cache预取:
处理器从一级Cache读取数据须要3~5个时 钟周期,二级是十几个时钟周期,三级是几十个时钟周期,而内存则需 要几百个时钟周期。DPDK必须保证全部须要读取的数据都在Cache中,不然一旦出现Cache不命中,性能将会严重降低。为了保证这点,DPDK采用 了多种技术来进行优化,预取只是其中的一种

6)利用UIO技术:
为了让驱动运行在用户态,Linux提供UIO机制。使用UIO能够经过read感知中断,经过mmap实现和网卡的通信

4.数据包处理流程

1)Linux传统方式处理数据包流程:

硬件中断--->取包分发至内核线程--->软件中断--->内核线程在协议栈中处理包--->处理完毕通知用户层
用户层收包-->网络层--->逻辑层--->业务层

2)DPDK处理数据包流程:

硬件中断--->放弃中断流程
用户层经过设备映射取包--->进入用户层协议栈--->逻辑层--->业务层

 5.学习目标

理解DPDK的内存机制, 以及处理数据包的流程

相关文章
相关标签/搜索