“零拷贝网络”与“内核绕过”?

Posted

技术标签:

【中文标题】“零拷贝网络”与“内核绕过”?【英文标题】:"zero copy networking" vs "kernel bypass"? 【发布时间】:2013-08-22 23:52:49 【问题描述】:

“零拷贝网络”和“内核绕过”有什么区别?这两个短语的意思是相同的,还是不同的?内核绕过是“零复制网络”中使用的一种技术吗?这就是关系?

【问题讨论】:

@alk Google“月亮是由奶酪制成的”,你会发现描述月亮是如何由奶酪制成的页面......我的意思是?太多不准确 - 我更相信关于 SO 的普遍共识。 谷歌搜索的艺术是提出正确的问题。而研究/调查的艺术是不要只相信一个来源的信息。 在零拷贝的主题中,我认为我们需要定义它发生的领域。我猜你问的是从应用程序(用户空间)到硬件(双向)的零拷贝,而不仅仅是在内核的网络堆栈层内 【参考方案1】:

“零拷贝网络”和“内核绕过”有什么区别?这两个短语的意思是相同的,还是不同的?内核绕过是“零复制网络”中使用的一种技术吗?这就是关系?

TL;DR - 它们是不同的概念,但内核绕过 API/框架很可能支持零拷贝。


用户绕过

也应该考虑这种通信方式。 DMA-to-DMA 事务可能完全不涉及 CPU。这个想法是使用splice() 或类似的函数来完全避免用户空间。注意,使用splice(),整个数据流不需要绕过用户空间。可以在用户空间中读取标头,并将数据直接流式传输到磁盘。最常见的缺点是 splice() 不执行校验和卸载。

零拷贝

零拷贝 的概念只是网络缓冲区固定在适当的位置,不会四处移动。在许多情况下,这并不是真正有益的。大多数现代网络硬件支持scatter gather,也称为缓冲区描述符等。这个想法是网络硬件理解物理指针。缓冲区描述符通常包括,

    数据指针 长度 下一个缓冲区描述符

好处是网络标头不需要并排IPTCP存在应用程序标头可以与应用程序数据物理上分开。

如果控制器不支持这一点,则 TCP/IP 标头必须位于 用户数据 之前,以便在发送到 网络控制器

零拷贝还意味着一些内核用户 MMU 设置,以便共享页面。

内核绕过

当然,你可以绕过内核。这就是pcap 和其他嗅探器软件已经做了一段时间的事情了。但是,pcap 不会阻止正常的内核处理;但这个概念类似于内核绕过框架所允许的。即,直接将数据包传递到将发生处理标头的用户空间。

但是,除非与特定的硬件相关联,否则很难看到 用户空间 会获得明确的胜利。某些网络控制器可能在控制器中支持分散聚集,而其他可能不支持。

有多种内核接口的化身来完成内核旁路。困难在于接收到的数据和产生用于传输的数据会发生什么。这通常涉及其他设备,因此有很多解决方案。


把这些放在一起......

这两个短语的意思是一样的还是不同的?

如上希望解释的那样,它们是不同的。

内核绕过是“零拷贝网络”中使用的一种技术吗?这就是关系吗?

恰恰相反。内核绕过可以使用零拷贝,并且很可能会支持它,因为缓冲区完全在应用程序的控制之下。此外,内核和用户空间之间没有内存共享(这意味着不需要 MMU 共享页面以及可能导致的任何缓存/TLB 影响)。所以如果你使用kernel bypass,支持零拷贝往往是有利的;所以一开始可能看起来是一样的。

如果 scatter-gather DMA 可用(大多数现代控制器),用户空间或内核都可以使用它。 零拷贝在这种情况下就没那么有用了。

参考:

Technical reference on OnLoad,一个高带宽内核旁路系统。 PF Ring 自 2.6.32 起(如果已配置) Linux kernel network buffer management大卫米勒。这让我们了解了如何在内核中管理协议标头/尾标。

【讨论】:

我不知道 Linux 是否支持 DMA 到 DMA 事务;但我知道有些硬件支持它。这个想法是以太网控制器磁盘控制器可以直接相互传输数据。这听起来比在用户空间中做事更有希望。 另请参阅***.com/q/15702601/632951,了解有关绕过 NIC 的更多信息。 @Pacerier 您在linux kernel bypass and perfromance 上的链接很好地解释了人们认为内核绕过 的不同表现形式。 RDMA 就像我的“DMA-to-DMA*”解释。对于嵌入式系统,可能有一个专用的“DMA 控制器”,可以修补大多数系统外围设备(NIC、磁盘、显示器、音频等),以在没有 CPU 的情况下传输数据。 有关用户绕过的更多详细信息,请参阅Splice and pipes in Linux。 是的,应用程序可以使用 pcap 接收传入的 IP 数据包并进行自己的 IP、TCP 和 UDP 处理,以让应用程序拥有自己的 Internet 协议栈,绕过内核的栈 - 只要它可以使这些 IP 数据包不受内核 IP 输入代码路径的控制 - 但这并不是很多(大多数?)使用 libpcap 的软件所做的。在这种情况下提及 pcap 并没有真正添加任何东西。【参考方案2】:

零拷贝网络

当您从未在用户空间和内核空间(我的意思是内存空间)之间复制数据时,您就是在进行零复制网络。举例:

C 语言 recv(fd, buffer, BUFFER_SIZE, 0);

默认情况下会复制数据:

    内核从网络栈中获取数据 内核将此数据复制到用户空间中的buffer

采用零拷贝方式,数据不被拷贝,直接从网络栈传到用户空间。

内核绕过

内核绕过是指您在用户空间、网络堆栈和硬件方面管理自己。这很难,但您将获得很多性能(零副本,因为所有数据都在用户空间中)。如果您想了解更多信息,这个link 可能会很有趣。

【讨论】:

你是说先完成零拷贝网络,然后“内核绕过”是下一个阶段,在用户空间处理零拷贝数据? 实际上“内核绕过”是一种实现零拷贝的方法。 @nouney: ...如果你做得好! ;-) 我问的原因是因为我在某处读到一个补丁已发布到 Linux 内核中以实现零拷贝。那么这是否意味着网络不再有内核绕过机会? Linux 默认已经这样做了...?? @user997112 您不必这样做,但可以。进行零拷贝的方法不止一种。阅读this long but good paper关于linux的零拷贝方法。【参考方案3】:

零拷贝:

在发送和接收数据包时, 所有数据包数据必须从 用户空间 缓冲区复制到 内核空间 缓冲区以进行传输,反之亦然以进行接收。 零复制驱动程序通过让用户空间和驱动程序直接共享数据包缓冲内存来避免这种情况。

不是让 transmitreceive 指向内核空间中稍后需要复制的缓冲区,而是分配用户空间中的一个内存区域,并将其映射到给定的物理内存区域,作为内核缓冲区和用户空间缓冲区之间的共享内存,然后将每个描述符缓冲区指向其在新分配的内存中的相应位置。

【讨论】:

【参考方案4】:

内核绕过和零拷贝的其他示例是 DPDK 和 RDMA。当应用程序使用 DPDK 时,它会绕过内核 TCP/IP 堆栈。该应用程序正在创建以太网帧,而 NIC 使用 DMA 直接从用户空间内存中抓取这些帧,因此它是零拷贝,因为没有从用户空间到内核空间的拷贝。应用程序可以使用 RDMA 做类似的事情。应用程序写入 NIC 直接访问和传输的队列对。 RDMA iblibverbs 也在内核内部使用,因此当 iSER 使用 RDMA 时,它不是内核绕过,而是零拷贝。

http://dpdk.org/

https://www.openfabrics.org/index.php/openfabrics-software.html

【讨论】:

以上是关于“零拷贝网络”与“内核绕过”?的主要内容,如果未能解决你的问题,请参考以下文章

操作系统-IO零拷贝

操作系统-IO零拷贝

零基础快速掌握JavaScript数组深拷贝与浅拷贝

传统IO拷贝与零拷贝技术比较

再学零拷贝与mmap

修改系统内核 绕过反调试 TracerPid为0