我试图做一些研究,我能理解的大部分内容是:DPDK 允许应用程序绕过 Linux 内核,减少一些复制和大量的 IRQ 请求。这就是全部?
DPDK 是一个软件库。正如(@Zac67 提到的)它有一个 EAL,它允许应用程序发送和接收 IP 数据包,而无需知道进行实际数据包转发的硬件。内核也为应用程序提供这种服务器,但 DPDK 的效率更高。
DPDK 通过 Linux 内核发送数据包提供的两个主要效率增益是:
多次复制相同的数据是非常低效的。
DPDK 批量运行数据包以提高缓存效率。
1:这有很大的不同。对于 Linux 上发送数据包的典型应用程序,当应用程序调用send()例如,系统调用,数据包从用户空间内存复制到内核内存(到 skbuff)。然后由 NIC 可访问的内核将 skbuff 复制到另一部分内存中。内核向 NIC 发出信号,表示有数据包等待发送,然后 NIC 将数据包从该内存区域(通过 DMA 传输 - 直接内存访问)复制到其硬件 tx-ring 缓冲区中。这意味着要从应用程序获取数据包并进入 NIC tx-ring 缓冲区,同一个数据包会被复制 3 次。DPDK 允许 NIC 直接从应用程序内存空间 DMA 数据包(通过 DPDK 断开 NIC 与内核的连接并将 DMA 内存空间映射到应用程序正在使用的用户空间内存空间,因此“内核旁路”) .
2:通过批处理数据包DPDK可以很好的利用CPU缓存。当 i-cache 预热时,要处理的第一个数据包将导致指令缓存未命中。该“批次”中的所有后续数据包都使用相同的指令非常快速地处理,这些指令现在在 i-cache 中是“热的”。
与使用标准内核 IP 堆栈相比,DPDK 中还有许多其他软件改进,但是,这两个改进对 DPDK 的性能有重大影响。
或者最新的 x86 CPU 也有硬件进步?也许一些新的指令?也许一些模板块?还是其他架构优化?硬件发生了什么变化?
是的,有硬件改进,例如更高效的 x86 CPU 上的新复制指令,并且 DPDK 支持这些(例如 SSE3 指令集)。主要的好处是软件的效率如何以及软件如何利用良好的硬件(例如,充分利用快速 CPU L1/L2 I-cache/D-cache)。DPDK 支持各种 IPSEC 和加密功能,因此如果您拥有带有 AES-NI 指令集(“高级加密标准 - 新指令”)的 Intel CPU,DPDK 将使用这些指令进行更快的 AES 加密/解密。
PS 如果绕过 Linux 内核 - 这就是 DPDK 所做的一切,我不明白,是什么阻止了这些优化,
内核可以通过以太网链路发送数据包,因此它会为 IP 数据包构建以太网标头,或者它可以通过 PPP、L2TP、IPSEC、GRE、MPLS、ATM、拨号等。Linux 内核非常灵活并且可以做很多事情,这意味着它必须进行许多检查并消耗 CPU 周期,以适应它支持的许多不同网络场景(Linux 主机可以是路由器、防火墙、交换机、代理等)。DPDK 支持以太网上的 IPv4 和 IPv6,仅此而已(是的,IPSEC 也是如此,但例如不支持 ATM!)。DPDK 仅提供内核执行的功能的子集,因此代码更专注于它的任务。另外附带说明一下,将更新批准到 Linux 内核的过程更加棘手,但一直在对 Linux 内核进行改进(见下文)。
以及为什么供应商需要花这么多钱来构建 ASIC 和其他员工,而他们可以编写新的操作系统或库,例如 DPDK……
ASIC 是针对特定任务进行调整/专用于特定任务的硬件(顾名思义,专用集成电路)。DPDK 永远不会像 ASIC 一样快(这句话在比较硬件和软件时并没有真正意义)。ASIC 旨在尽可能高效地完成特定任务。DPDK 在 x86 通用 CPU 上运行,它们具有许多奇怪而美妙的功能,因为它们可以用于任何任务/工作负载。DPDK 尝试为网络处理器的特定任务充分利用通用 x86 进程,而 ASIC 是预先构建的,以便在网络处理方面高效。
关于 Linux 网络速度的旁注:
我一直在编写这个工具(仍在进行中)来比较发送数据包的不同内核方法:https : //github.com/jwbensley/EtherateMT
当使用一个 CPU 内核和一个框架时64 字节的大小我得到以下不同内核方法的
send()每秒
sendmsg()帧率:1.00Mfps 1.01Mfps
sendmmsg()1.2Mfps
TPACKET_V2 1.3Mfps
TPACKET_V3 1.3Mfps
从这些数字的角度来看,使用 64 字节数据包的 10Gbps 是 14.48Mpps,DPDK 可以在单个 CPU 内核上实现。因此,本机内核路径要慢一个数量级,但是,TPACKETV_v4 刚刚发布,其中包括零复制选项,这应该会带来主要的速度提升。
编辑:我忘了说,DPDK 有缺点,例如,您需要一个 DPDK 明确支持的 NIC。一直在努力增加支持的 NIC 列表。这是因为 DPDK 使用自己的驱动程序。不过,Linux 还支持数以千计的 NIC,因为它非常灵活并且具有标准的驱动程序实现方法,因此任何带有兼容驱动程序的 NIC 都应该可以工作。这是使用 DPDK 获得的速度的另一个权衡。
编辑2:
但是,这种数据包处理的“批处理方法”不是会导致延迟增加吗?
Linux 内核内置了对数据包的批处理功能。您可以关闭此功能,对于 NIC 接收到的每个数据包,都会生成硬件中断,内核会发出信号以读取和处理数据包。这具有很高的处理开销,但正如您所说,它会减少延迟。由于单独处理每个数据包的额外开销,它还会降低带宽,每秒可以处理的数据包更少。只有在需要时,才可以在 Linux 上使用中断合并来批处理数据包。中断合并会自动调整生成硬件中断的频率。硬件中断可以被速率限制为每 30us 仅生成一次,例如,当 NIC 接收到 1 个或多个数据包等待内核处理它们时。这会增加带宽和延迟。中断合并可以根据进入 NIC 等待处理的数据包的数量自动增加或减少中断速率限制。如果您需要非常低的延迟,例如金融交易员,您可以关闭中断合并以减少带宽以减少延迟。
在同一数据包处理框架(例如 Linux 内核)中比较批处理与按数据包处理时,需要在延迟与带宽之间进行权衡,正如我刚刚描述的那样。然而,关于这个 NE 问题,DPDK 中的批处理非常高效,当将 DPDK 批处理包处理与 Linux 内核中的批处理和按包处理进行比较时,DPDK 仍然快 10 倍,延迟更低。DPDK 的关键在于它是专门编写的高性能代码,并且 Linux 内核在全球数百万台机器上运行,这意味着它非常灵活以换取性能。