使用和不使用Scatter/Gather操作进行零拷贝

sli*_*ter 6 c linux network-programming linux-kernel zero-copy

我刚读了一篇解释零拷贝机制的文章.

它讨论了有和没有Scatter/Gather支持的零拷贝之间的区别.

网卡没有SG支持,数据副本如下

在此输入图像描述

NIC支持SG,数据副本如下

在此输入图像描述

总之,使用SG支持的零拷贝可以消除一个CPU拷贝.

我的问题是为什么内核缓冲区中的数据可能会分散

Fra*_*kH. 15

因为默认情况下Linux内核的映射/内存分配工具会创建几乎连续但可能是物理上不相交的内存区域.
这意味着文件系统的读取会在sendfile()内部进入内核虚拟内存中的缓冲区,DMA代码必须将"transmogrify"(缺少更好的词)转换为网卡的DMA引擎可以查看的内容.

由于DMA(通常但并非总是)使用物理地址,这意味着您要么复制数据缓冲区(进入一个特殊分配的物理上连续的内存区域,上面的套接字缓冲区),要么将其传输到一个物理页面- 一次.

另一方面,如果您的DMA引擎能够将多个物理上不相交的内存区域聚合成单个数据传输(称为"分散 - 聚集"),那么您可以简单地传递一个物理地址列表,而不是复制缓冲区. (指向内核缓冲区的物理上连续的子段,这是上面的聚合描述符),您不再需要为每个物理页面启动单独的DMA传输.这通常更快,但是否可以完成取决于DMA引擎的功能.