DPDK性能影响因素分析
上篇请参阅“DPDK技术原理与架构”,本篇为下篇。介绍基于 DPDK 进行应用开发和环境配置时,应用程序性能的影响因素以及相应的 优化调整方法。这些因素并非必然劣化性能,可能因硬件能力、OS 版本、各类软硬环境参数配置等的差异产生较大波动,或者存在较大的不稳定性,相关的调优方法需要用户结合自身的VNF应用部署在实践中不断完善。
更多关于DPDK技术内容请 参考“ 《中国电信DPDK技术白皮书v1.0》 ”。
中国电信DPDK技术白皮书v1.0 DPDK基础—认识DPDK技术 DPDK架构高清版 DPDK编程指南(中文版)
1、 硬件结构的影响
DPDK 具有广泛的平台适应性,可以运行在整个 x86 平台,从主流服务器平台(从高性 能或者高能效产品系列),到桌面或者嵌入式平台,也可以运行于基于 Power 或者其他架构 的运算平台。图展示了一个通用双路服务器的内部架构,它包含了 2 个中央处理器,2个分离的内存控制单元来连接系统内存,芯片组会扩展出大量高速的 PCIe 2.0/3.0 接口,用于连接外设,如 10Gbps 或者 25Gbps 网卡外设。
2、OS 版本及其内核的影响
不同的 Linux OS 发行版使用的 Linux 内核版本不一样,配置的 Linux OS服务也不一样。 这些差异都会导致应用程序在网络报文处理能力上有所差别。
由于 Linux 内核还在不断演进,Linux 的发行版也数量众多,本文无法提供最佳 Linux 内核版本和配置,而只能给出部分参考建议,如:关闭部分 OS 服务。在后续章节,我们选取了目前比较流行的 Linux 发行版进行了测试,并给出测试结果。从测试结果中显示,同样的硬件配置环境下,不同的 Linux 发行版在小包的处理能力上存在差异。
2.1 关闭 OS 部分服务
在 10G 端口上 64Byte 报文的线速到达率为 14.88Mpps,如果实现零丢包的线速处理, 每个报文的平均处理速度应该小于 1/14.48Mpps=67us,DPDK 应用的网卡收发包队列长度缺 省配置为 128,网卡队列填充满的时间是 128*67=8579us。也就是说,DPDK 的业务进程,如果被操作系统中断超过 8579us,就会导致网卡收发报的队列被充满,无法接收新的报文,从而导致丢包。而操作系统的中断服务程序、后台服务程序、以及任务调度程序都会导致 DPDK 的应用程序被打断。
在 NFV 应用场景下,Host 机器上和 Guest 机器上都运行着操作系统,由此带来了两级 的操作任务调度。DPDK 应用程序(NFV 中的 VNF)均运行在虚拟机上,操作系统带来的影响 会更加明显。
为了实现 DPDK 应用程序的零丢包,需要对操作系统进行适当的配置,减少操作系统的 对 DPDK 应用程序的干扰。操作系统配置的总体思路是:
•将运行 DPDK 应用运行的处理器核进行隔离,减少干扰; •停用不需要的后台服务程序。将不需要的中断,转移到其它处理器核上处理; •对于不能转移的中断,减少中断的次数。
2.2、OS 调整示例
下面以 CentOS 7 为例,说明具体的调整方法。绝大部分的操作需要同时在 Host 操作系 统和 Guest 操作系统同时应用。
1) 对 DPDK 应用使用处理器核进行隔离 修改 Linux 的 OS 的 GRUB 参数, 设置 isolCPUs=16-23,40-47
2) 打开运行有 DPDK 进程的处理器核上的 nohz_full。nohz_full 可以减少内核的周期性时 钟中断的次数。 修改 Linux 的 OS 的 GRUB 参数, 设置 nohz_full=16-23,40-47
3) 关闭 NMI 监控功能,减少 NMI 中断对 DPDK 任务的干扰。 修改 Linux 的 OS 的 GRUB 参数, 设置 nmi_watchdog=0
4) 关闭 SELinux 功能 修改 Linux 的 OS 的 GRUB 参数, 设置 selinux=0
5) 关闭处理器的 P 状态调整和 softlockup 功能。将处理器锁定在固定的频率运行,减少 处理器在不同的 P 状态切换带来的处理时延。 修改 Linux 的 OS 的 GRUB 参数, 设置 intel_pstate=disable nosoftlockup
6) 关闭图形显示,减少 GUI 应用的干扰 调用命令 systemctl set-default multi-user.target 7) 关闭操作系统的中断调度程序 调用命令 systemctl disable irqbalance.service 8) 关闭操作系统的审计服务 调用命令 systemctl disable auditd.service 9) 关闭蓝牙服务 调用命令 systemctl disable bluetooth.service 10) 关闭 KVM 的内存页合并服务 调用命令 systemctl disable ksm.service 调用命令 systemctl disable ksmtuned.service 11) 对于 KVM 虚拟的 vCPU 和物理 CPU 进行绑定 使用 QEMU monitor 获取 vCPU 对应的线程号,使用 taskset 命令进行绑定。
2.3、OVS 性能问题
OVS 作为 NFV 的一个重要组成模块,会运行在绝大多数的服务器节点上,提供虚拟机和 虚拟机之间,以及虚拟网络和物理网络间的互连接口,其性能至关重要。 OVS 2.4 开始正式 支持 DPDK 加速,相比传统基于 Linux 内核的 OVS 版本,转发性能提高了数倍,为 VNF 在通 用 x86 服务器上部署提供了有力支持。
OVS 缺省会为每一个 NUMA 节点创建一个 pmd 线程,该 pmd 线程以轮询方式处理属于其 NUMA 节点上的所有 DPDK 接口。为了高性能,需要利用前面提到的 CPU 亲和技术,把 pmd 线 程绑定在一个固定的 CPU core 上处理。此外,为了增加扩展性,OVS 2.4 也支持网卡多队列以及多 pmd 线程数,这些参数均可动态配置,但具体配置应根据具体需求来决定。
4、 内存管理
如前所述,DPDK 考虑了 NUMA 以及多内存通道的访问效率,会在系统运行前要求配置 Linux 的 HugePage,初始化时申请其内存池,用于 DPDK 运行的主要内存资源。 Linux 大页 机制利用了处理器核上的的 TLB 的 HugePage 表项,这可以减少内存地址转换的开销。
4.1 内存多通道的使用
现代的内存控制器都支持内存多通道,比如 Intel 的 E5-2600V3 系列处理器,能支持 4 个通道,可以同时读和取数据。依赖于内存控制器及其配置,内存分布在这些通道上。每一 个通道都有一个带宽上限,如果所有的内存访问都只发生在第一个通道上,这将成为一个潜 在的性能瓶颈。
因此,DPDK 的 mempool 库缺省是把所有的对象分配在不同的内存通道上,保证了在系 统极端情况下需要大量内存访问时,尽可能地将内存访问任务均匀平滑。
4.2 内存拷贝
很多 libc 的 API 都没有考虑性能,因此,不要在高性能数据平面上用 libc 提供的 API, 比如,memcpy()或 strcpy()。虽然 DPDK 也用了很多 libc 的 API,但均只是在软件配置方面 用于方便程序移植和开发。
DPDK 提供了一个优化版本的 rte_memcpy() API,它充分利用了 Intel 的 SIMD 指令集, 也考虑了数据的对齐特性和 cache 操作友好性。
4.3 内存分配
在某些情况下,应用程序使用 libc 提供的动态内存分配机制是必要的,如 malloc()函 数,它是一种灵活的内存分配和释放方式。但是,因为管理零散的堆内存代价昂贵,并且这 种内存分配器对于并行的请求分配性能不佳,所以不建议在数据平面处理上使用类似 malloc()的函数进行内存分配。
在有动态分配的需求下,建议使用 DPDK 提供的 rte_malloc() API,该 API 可以在后台 保证从本 NUMA 节点内存的 HugePage 里分配内存,并实现 cache line 对齐以及无锁方式访 问对象等功能。
4.4 NUMA 考虑
NUMA(Non Uniform Memory Access Architecture)与 SMP(Symmetric Multi Processing) 是两种典型的处理器对内存的访问架构。 随着处理器进入多核时代,对于内存吞吐量和延迟 性能有了更高的要求,NUMA 架构已广泛用于最新的英特尔处理器中,为每个处理器提供分 离的内存和内存控制器,以避免 SMP 架构中多个处理器同时访问同一个存储器产生的性能损 失。
在双路服务器平台上,NUMA 架构存在本地内存与远端内存的差异。本地和远端是个相 对概念,是指内存相对于具体运行程序的处理器而言,如图所示。
在 NUMA 体系架构中,CPU 进行内存访问时,本地内存的要比访问远端内存更快。因为 访问远端内存时,需要跨越 QPI 总线,在应用软件设计中应该尽量避免。 在高速报文处理中, 这个访问延迟会大幅降低系统性能。 尤其是传统嵌入式软件向服务器平台迁移时,需要特别 关注。
DPDK 提供了一套在指定 NUMA 节点上创建 memzone、ring, rte_malloc 以及 mempool 的 API,可以避免远端内存访问这类问题。 在一个 NUMA 节点端,对于内存变量进行读取不会存 在性能问题,因为该变量会在 CPU cache 里。 但对于跨 NUMA 架构的内存变量读取,会存在 性能问题,可以采取复制一份该变量的副本到本地节点(内存)的方法来提高性能。
5、CPU 核间无锁通信 如果想建立一个基于消息传递的核间通信机制,可以使用 DPDK ring API,它是一个无 锁的 ring 实现。该 ring 机制支持批量和突发访问,即使同时读取几个对象,也只需要一个 昂贵的原子操作,批量访问可以极大地改善性能。
6 设置正确的目标 CPU 类型
DPDK支持CPU微架构级别的优化,可以通过修改DPDK配置文件中的CONFIG_RTE_MACHINE 参数来定义。优化的程度根据随编译器的能力而不同,通常建议采用最新的编译器进行编译。
如果编译器的版本不支持该款 CPU 的特性,比如 Intel AVX 指令,那么它在编译时只会选用 自己支持的指令集,这可能导致编译 后生成的 DPDK 应用的性能下降。
上篇请参阅“DPDK技术原理与架构”,本篇为下篇。介绍基于 DPDK 进行应用开发和环境配置时,应用程序性能的影响因素以及相应的 优化调整方法。这些因素并非必然劣化性能,可能因硬件能力、OS 版本、各类软硬环境参数配置等的差异产生较大波动,或者存在较大的不稳定性,相关的调优方法需要用户结合自身的VNF应用部署在实践中不断完善。
更多关于DPDK技术内容请 参考“ 《中国电信DPDK技术白皮书v1.0》 ”。
中国电信DPDK技术白皮书v1.0 DPDK基础—认识DPDK技术 DPDK架构高清版 DPDK编程指南(中文版)
1、 硬件结构的影响
DPDK 具有广泛的平台适应性,可以运行在整个 x86 平台,从主流服务器平台(从高性 能或者高能效产品系列),到桌面或者嵌入式平台,也可以运行于基于 Power 或者其他架构 的运算平台。图展示了一个通用双路服务器的内部架构,它包含了 2 个中央处理器,2个分离的内存控制单元来连接系统内存,芯片组会扩展出大量高速的 PCIe 2.0/3.0 接口,用于连接外设,如 10Gbps 或者 25Gbps 网卡外设。
2、OS 版本及其内核的影响
不同的 Linux OS 发行版使用的 Linux 内核版本不一样,配置的 Linux OS服务也不一样。 这些差异都会导致应用程序在网络报文处理能力上有所差别。
由于 Linux 内核还在不断演进,Linux 的发行版也数量众多,本文无法提供最佳 Linux 内核版本和配置,而只能给出部分参考建议,如:关闭部分 OS 服务。在后续章节,我们选取了目前比较流行的 Linux 发行版进行了测试,并给出测试结果。从测试结果中显示,同样的硬件配置环境下,不同的 Linux 发行版在小包的处理能力上存在差异。
2.1 关闭 OS 部分服务
在 10G 端口上 64Byte 报文的线速到达率为 14.88Mpps,如果实现零丢包的线速处理, 每个报文的平均处理速度应该小于 1/14.48Mpps=67us,DPDK 应用的网卡收发包队列长度缺 省配置为 128,网卡队列填充满的时间是 128*67=8579us。也就是说,DPDK 的业务进程,如果被操作系统中断超过 8579us,就会导致网卡收发报的队列被充满,无法接收新的报文,从而导致丢包。而操作系统的中断服务程序、后台服务程序、以及任务调度程序都会导致 DPDK 的应用程序被打断。
在 NFV 应用场景下,Host 机器上和 Guest 机器上都运行着操作系统,由此带来了两级 的操作任务调度。DPDK 应用程序(NFV 中的 VNF)均运行在虚拟机上,操作系统带来的影响 会更加明显。
为了实现 DPDK 应用程序的零丢包,需要对操作系统进行适当的配置,减少操作系统的 对 DPDK 应用程序的干扰。操作系统配置的总体思路是:
•将运行 DPDK 应用运行的处理器核进行隔离,减少干扰; •停用不需要的后台服务程序。将不需要的中断,转移到其它处理器核上处理; •对于不能转移的中断,减少中断的次数。
2.2、OS 调整示例
下面以 CentOS 7 为例,说明具体的调整方法。绝大部分的操作需要同时在 Host 操作系 统和 Guest 操作系统同时应用。
1) 对 DPDK 应用使用处理器核进行隔离 修改 Linux 的 OS 的 GRUB 参数, 设置 isolCPUs=16-23,40-47
2) 打开运行有 DPDK 进程的处理器核上的 nohz_full。nohz_full 可以减少内核的周期性时 钟中断的次数。 修改 Linux 的 OS 的 GRUB 参数, 设置 nohz_full=16-23,40-47
3) 关闭 NMI 监控功能,减少 NMI 中断对 DPDK 任务的干扰。 修改 Linux 的 OS 的 GRUB 参数, 设置 nmi_watchdog=0
4) 关闭 SELinux 功能 修改 Linux 的 OS 的 GRUB 参数, 设置 selinux=0
5) 关闭处理器的 P 状态调整和 softlockup 功能。将处理器锁定在固定的频率运行,减少 处理器在不同的 P 状态切换带来的处理时延。 修改 Linux 的 OS 的 GRUB 参数, 设置 intel_pstate=disable nosoftlockup
6) 关闭图形显示,减少 GUI 应用的干扰 调用命令 systemctl set-default multi-user.target 7) 关闭操作系统的中断调度程序 调用命令 systemctl disable irqbalance.service 8) 关闭操作系统的审计服务 调用命令 systemctl disable auditd.service 9) 关闭蓝牙服务 调用命令 systemctl disable bluetooth.service 10) 关闭 KVM 的内存页合并服务 调用命令 systemctl disable ksm.service 调用命令 systemctl disable ksmtuned.service 11) 对于 KVM 虚拟的 vCPU 和物理 CPU 进行绑定 使用 QEMU monitor 获取 vCPU 对应的线程号,使用 taskset 命令进行绑定。
2.3、OVS 性能问题
OVS 作为 NFV 的一个重要组成模块,会运行在绝大多数的服务器节点上,提供虚拟机和 虚拟机之间,以及虚拟网络和物理网络间的互连接口,其性能至关重要。 OVS 2.4 开始正式 支持 DPDK 加速,相比传统基于 Linux 内核的 OVS 版本,转发性能提高了数倍,为 VNF 在通 用 x86 服务器上部署提供了有力支持。
OVS 缺省会为每一个 NUMA 节点创建一个 pmd 线程,该 pmd 线程以轮询方式处理属于其 NUMA 节点上的所有 DPDK 接口。为了高性能,需要利用前面提到的 CPU 亲和技术,把 pmd 线 程绑定在一个固定的 CPU core 上处理。此外,为了增加扩展性,OVS 2.4 也支持网卡多队列以及多 pmd 线程数,这些参数均可动态配置,但具体配置应根据具体需求来决定。
4、 内存管理
如前所述,DPDK 考虑了 NUMA 以及多内存通道的访问效率,会在系统运行前要求配置 Linux 的 HugePage,初始化时申请其内存池,用于 DPDK 运行的主要内存资源。 Linux 大页 机制利用了处理器核上的的 TLB 的 HugePage 表项,这可以减少内存地址转换的开销。
4.1 内存多通道的使用
现代的内存控制器都支持内存多通道,比如 Intel 的 E5-2600V3 系列处理器,能支持 4 个通道,可以同时读和取数据。依赖于内存控制器及其配置,内存分布在这些通道上。每一 个通道都有一个带宽上限,如果所有的内存访问都只发生在第一个通道上,这将成为一个潜 在的性能瓶颈。
因此,DPDK 的 mempool 库缺省是把所有的对象分配在不同的内存通道上,保证了在系 统极端情况下需要大量内存访问时,尽可能地将内存访问任务均匀平滑。
4.2 内存拷贝
很多 libc 的 API 都没有考虑性能,因此,不要在高性能数据平面上用 libc 提供的 API, 比如,memcpy()或 strcpy()。虽然 DPDK 也用了很多 libc 的 API,但均只是在软件配置方面 用于方便程序移植和开发。
DPDK 提供了一个优化版本的 rte_memcpy() API,它充分利用了 Intel 的 SIMD 指令集, 也考虑了数据的对齐特性和 cache 操作友好性。
4.3 内存分配
在某些情况下,应用程序使用 libc 提供的动态内存分配机制是必要的,如 malloc()函 数,它是一种灵活的内存分配和释放方式。但是,因为管理零散的堆内存代价昂贵,并且这 种内存分配器对于并行的请求分配性能不佳,所以不建议在数据平面处理上使用类似 malloc()的函数进行内存分配。
在有动态分配的需求下,建议使用 DPDK 提供的 rte_malloc() API,该 API 可以在后台 保证从本 NUMA 节点内存的 HugePage 里分配内存,并实现 cache line 对齐以及无锁方式访 问对象等功能。
4.4 NUMA 考虑
NUMA(Non Uniform Memory Access Architecture)与 SMP(Symmetric Multi Processing) 是两种典型的处理器对内存的访问架构。 随着处理器进入多核时代,对于内存吞吐量和延迟 性能有了更高的要求,NUMA 架构已广泛用于最新的英特尔处理器中,为每个处理器提供分 离的内存和内存控制器,以避免 SMP 架构中多个处理器同时访问同一个存储器产生的性能损 失。
在双路服务器平台上,NUMA 架构存在本地内存与远端内存的差异。本地和远端是个相 对概念,是指内存相对于具体运行程序的处理器而言,如图所示。
在 NUMA 体系架构中,CPU 进行内存访问时,本地内存的要比访问远端内存更快。因为 访问远端内存时,需要跨越 QPI 总线,在应用软件设计中应该尽量避免。 在高速报文处理中, 这个访问延迟会大幅降低系统性能。 尤其是传统嵌入式软件向服务器平台迁移时,需要特别 关注。
DPDK 提供了一套在指定 NUMA 节点上创建 memzone、ring, rte_malloc 以及 mempool 的 API,可以避免远端内存访问这类问题。 在一个 NUMA 节点端,对于内存变量进行读取不会存 在性能问题,因为该变量会在 CPU cache 里。 但对于跨 NUMA 架构的内存变量读取,会存在 性能问题,可以采取复制一份该变量的副本到本地节点(内存)的方法来提高性能。
5、CPU 核间无锁通信 如果想建立一个基于消息传递的核间通信机制,可以使用 DPDK ring API,它是一个无 锁的 ring 实现。该 ring 机制支持批量和突发访问,即使同时读取几个对象,也只需要一个 昂贵的原子操作,批量访问可以极大地改善性能。
6 设置正确的目标 CPU 类型
DPDK支持CPU微架构级别的优化,可以通过修改DPDK配置文件中的CONFIG_RTE_MACHINE 参数来定义。优化的程度根据随编译器的能力而不同,通常建议采用最新的编译器进行编译。
如果编译器的版本不支持该款 CPU 的特性,比如 Intel AVX 指令,那么它在编译时只会选用 自己支持的指令集,这可能导致编译 后生成的 DPDK 应用的性能下降。
转载申明:转载 本号文章请注明作者和来源,本号发布文章若存在版权等问题,请留言联系处理,谢谢。
推荐阅读
更多架构相关技术知识总结请参考“架构师全店铺技术资料打包”相关电子书(37本技术资料打包汇总详情可通过“ 阅读原文 ”获取)。
全店内容持续更新,现下单“架构师技术全店资料打包汇总(全)”,后续可享全店内容更新“免费”赠阅,价格仅收198元(原总价 350 元)。
温馨提示:
扫描 二维码 关注公众号,点击 小程序 链接 获取 “ 架构师技术联盟书店 ” 电子书资料详情 。
评论