DPDK简介之二

前沿

DPDK是专为快速收发包所开发的一系列的库文件和驱动代码。可以在Intel的芯片上运行。可以用来在极短的时间里面完成收发包(一般低于80个周期)。可以运行第三方的快速路径栈而DPDK最大的优点就是改进小封包吞吐量与作业负荷效能,传统的网路架构都是针对大封包吞吐量进行最佳化,而Intel® DPDK可以解决小封包所带来效能不佳的问题。除了应用在企业终端外, Intel DPDK 也可以在软件定义网路 (SDN) 与网路功能虚拟化 (NFV) 中扮演着重要的角色。

基本概念

UIO

UIO指的是运行在用户空间的I/O技术,是实现用户空间下驱动程序的支撑机制。在用户空间用应用程序调用即可,而UIO则是将驱动的很少一部分运行在内核空间,而在用户空间实现驱动的绝大多数功能。使用UIO可以避免设备的驱动程序需要随着内核的更新而更新的问题。由于DPDK是应用层平台,所以与此紧密相连的网卡驱动程序(主要是intel自身的千兆igb与万兆ixgbe驱动程序)都通过uio机制运行在用户态下。 Intel® DPDK 的igb_uio内核模块依赖于内核的UIO。 需要以模块方式编译可以通过如下命令进行编译
sudo /sbin/modprobe uio

Hugepages 机制

大内存页指的是为包处理的缓冲区缓冲区分配更大的大内存池,利用大内存页的主要好处当然是通过利用大内存页提高内存使用效率。可以得到明显的性能提高,因为需要更少的页,更少的TLB( Translation Lookaside Buffers),减少了虚拟页地址到物理页地址的转换时间。如果不使用大内存页机制的话,TLB的命中率会降低,反而会降低性能。大内存页最好在启动的时候进行分配,这样可以避免物理空间中有太多的碎片,提高发包的效率。普通的页大小为4KB, 默认的大内存页的大小为2MB,也可以设置其他的大内存页大小,可以从CPU的标识中看出支持哪种大内存页,如果有 “pse”的标识,说明支持2M的大内存页。 如果有“pdpe1gb”的标识,说明支持1G的大内存页,如果64位机建议使用1GB的大页。

如何使用大内存页

如果已经配置好了大内存页机制,就可以让DPDK利用大内存页的机制了。
可以输入如下的命令
mkdir /mnt/huge
mount -t hugetlbfs nodev /mnt/huge
在运行程序 的时候,最好把分配给大页的所有空间都利用起来。如果DPDK的程序在运行的时候传递了-m 或者–socket-mem的参数,大内存页的分配在启动的时候会自动加载。如果传递给程序的内存页数量比程序要求的要少,也就是内存页不够用,程序将会中止。

TLB

其中TLB(Translation Lookaside Buffer)指的是旁路转换缓冲,或称为页表缓冲,是一个存放着页表缓存(虚拟地址到物理地址的转换表)的内存管理单元,用于改进虚拟地址到物理地址转换速度。
X86体系的系统内存里存放了两级页表,第一级页表称为页目录,第二级称为页表。由于“页表”存储在主存储器中,查询页表所付出的代价很大,由此产生了TLB。
TLB是内存里存放的页表的缓存,那么它里边存放的数据实际上和内存页表区的数据是一致的,在内存的页表区里,每一条记录虚拟页面和物理页框对应关系的记录称之为一个页表条目(Entry),同样地,在TLB里边也缓存了同样大小的页表条目(Entry)。

1:在X86体系的CPU里边,一般都设有如下4组TLB:
第一组:缓存一般页表(4K字节页面)的指令页表缓存(Instruction-TLB);
第二组:缓存一般页表(4K字节页面)的数据页表缓存(Data-TLB);
第三组:缓存大尺寸页表(2M/4M字节页面)的指令页表缓存(Instruction-TLB);
第四组:缓存大尺寸页表(2M/4M字节页面)的数据页表缓存(Data-TLB);
2:TLB命中和TLB失败
如果TLB中正好存放着所需的页表,则称为TLB命中(TLB Hit);
如果TLB中没有所需的页表,则称为TLB失败(TLB Miss)。
当CPU收到应用程序发来的虚拟地址后,
首先到TLB中查找相应的页表数据,如果TLB中正好存放着所需的页表,则称为TLB命中(TLB Hit)
接下来CPU再依次看TLB中页表所对应的物理内存地址中的数据是不是已经在一级、二级缓存里了,若没有则到内存中取相应地址所存放的数据。

CPU的物理核,逻辑核概念

一个物理封装的CPU(通过physical id区分判断)可以有多个核(通过core id区分判断)。而每个核可以有多个逻辑cpu(通过processor区分判断)。一个核通过多个逻辑cpu实现这个核自己的超线程技术。

物理处理器封装个数

Sockets, 中文翻译成“插槽”,也就是所谓的物理处理器封装个数,即俗称的“物理CPU数”,管理员可能会称之为“路”。
例如一块“Intel Core i3-2310M”只有1个“物理处理器封装个数”。若对于有多个处理器插槽的服务器,“物理处理器封装个数”很可能会大于1。
可以使用如下命令查询物理处理器的封装个数。
cat /proc/cpuinfo| grep “physical id”| sort| uniq| wc –l
具有相同physical id的CPU是同一个CPU封装的线程或核心
或者使用
lscpu | grep “CPU socket”(iscpu可以看到很多cat /proc/cpuinfo看不到的东西,建议使用)

处理器核心数

processor cores,即俗称的“CPU核心数”,也就是每个物理CPU中core的个数
例如“Intel Core i3-2310M”是双核处理器,它有2个“处理器核心数”。
可以通过以下的命令来查看:
cat /proc/cpuinfo| grep “cpu cores”| uniq
具有相同core id的CPU是同一个core的超线程

逻辑处理器数

逻辑处理器数英文名是logical processors,即俗称的“逻辑CPU数”,
逻辑核心处理器,就是虚拟物理核心处理器的一个超线程技术
例如“Intel Core i3-2310M”支持超线程,一个物理核心能模拟为两个逻辑处理器,即一块“Intel Core i3-2310M”有4个“逻辑处理器数”。
可以使用
cat /proc/cpuinfo| grep “processor”| wc –l

SIBLING

SIBLING是内核认为的单个物理处理器所有的超线程个数,也就是一个物理封装中的逻辑核的个数。

如果SIBLING等于实际物理核数的话,就说明没有启动超线程,反之启用超线程。
也就是说使用cat /proc/cpu命令

如果“siblings”和“cpu cores”一致,则说明不支持超线程,或者超线程未打开。
如果“siblings”是“cpu cores”的两倍,则说明支持超线程,并且超线程已打开

超线程

超线程全名为Hyper-Threading,利用特殊的硬件指令,把两个逻辑内核模拟成两个物理芯片,让单个处理器都能使用线程级并行计算,进而兼容多线程操作系统和软件,减少了CPU的闲置时间,提高的CPU的运行速度。

采用超线程即是可在同一时间里,应用程序可以使用芯片的不同部分。
虽然单线程芯片每秒钟能够处理成千上万条指令,但是在任一时刻只能够对一条指令进行操作。而超线程技术可以使芯片同时进行多线程处理,使芯片性能得到提升。

虽然采用超线程技术能同时执行两个线程,但它并不象两个真正的CPU那样,每个CPU都具有独立的资源。当两个线程都同时需要某一个资源时,其中一个要暂时停止,并让出资源,直到这些资源闲置后才能继续。因此超线程的性能并不等于两颗CPU的性能。

如果有两个逻辑CPU具有相同的”core id”,那么超线程是打开的。

CPU亲和性

CPU的亲和性也就是cpu affinity机制,指的是进程要在指定的 CPU 上尽量长时间地运行而不被迁移到其他处理器, 通过处理器关联可以将虚拟处理器映射到一个或多个物理处理器上 , 也就是说把一个程序绑定到一个物理CPU上。

在越来越多核心的cpu机器上,如何提高外设以及程序工作效率的最直观想法就是让各个cpu核心各自干专门的事情。而且在多核运行的机器上,每个CPU本身自己会有缓存,缓存着进程使用的信息,而进程可能会被OS调度到其他CPU上,如此,CPU cache命中率就低了,当绑定CPU后,程序就会一直在指定的cpu跑,不会由操作系统调度到其他CPU上,性能有一定的提高。

另外一种使用绑核考虑就是将重要的业务进程隔离开,对于部分实时进程调度优先级高,可以将其绑定到一个指定核上,既可以保证实时进程的调度,也可以避免其他CPU上进程被该实时进程干扰。

DPDK利用cpu affinity主要是将控制面线程以及各个数据面线程绑定到不同的cpu,省却了来回反复调度的性能消耗,线程之间互不干扰的完成工作。

编译DPDK工具链

把从官网下到的DPDK的安装包,并解压以后可以得到如下的目录
user@droid:~/rte-source$ ls
app/ config/ examples/ lib/ LICENSE.GPL LICENSE.LGPL Makefile mk/ scripts/ tools/

• lib: DPDK的库函数
• app:的应用的源文件
• examples:应用的一些例程源码
• config, tools, scripts, mk: makefiles,脚本和一些配置文件。

指得一提的是,官方文档中约定rte-source为软件解压的目录路径。

加载DPDK igb_uio模块

要运行DPDK的所有程序,必须首先加载igb_uio模块。 Linux系统中一般的驱动设备都是运行在内核空间,但是DPDK是应用层平台,所以与此紧密相连的网卡驱动程序都通过uio机制运行在用户态下。可以使用如下命令加载模块:
sudo insmod kmod/igb_uio.ko

网络端口绑定到igb_uio上

dpdk会让网卡脱离系统内核,重新绑定到igb_uio上,然会从用户态里去控制网卡,可以在执行程序的时候使用-b的选项让某个端口不被解绑。一定从内核驱动中解绑,从系统角度是看不到这张网卡,也就是说通过ifconfig命令,看不到这张网卡的信息,而且所有网络应该程序也都用不了这张网卡。要用这个网卡,就需要用DPDK的API来写发包,收包程序。如果这个网卡要配IP,则需要在程序里自已实现TCP/IP协议。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章