程序员必知必会的零拷贝技术( 二 )

程序员必知必会的零拷贝技术
文章插图
 
可以看到 , 与使用read()和write()发送文件相比 , 使用sendfile()减少了一次 I/O 拷贝和两次 上下文切换 。
sendfile with DMA Gather Copy为了避免操作系统内核造成的数据副本 , 需要用到一个支持收集操作的网络接口 , 这也就是说 , 待传输的数据可以分散在存储的不同位置上 , 而不需要在连续存储中存放 。
这样一来 , 从文件中读出的数据就根本不需要被拷贝到 socket 缓冲区中去 , 而只是需要将缓冲区描述符传到网络协议栈中去 , 之后其在缓冲区中建立起数据包的相关结构 , 然后通过 DMA 收集拷贝功能将所有的数据结合成一个网络数据包 。

程序员必知必会的零拷贝技术

文章插图
 
网卡的 DMA 引擎会在一次操作中从多个位置读取包头和数据 。Linux 2.4 版本中的 socket 缓冲区就可以满足这种条件 , 这也就是用于 Linux 中的众所周知的零拷贝技术 , 这种方法不但减少了因为多次上下文切换所带来开销 , 同时也减少了处理器造成的数据副本的个数 。
对于用户应用程序来说 , 代码没有任何改变 。首先 , sendfile() 系统调用利用 DMA 引擎将文件内容拷贝到内核缓冲区去;然后 , 将带有文件位置和长度信息的缓冲区描述符添加到 socket 缓冲区中去 , 此过程不需要将数据从操作系统内核缓冲区拷贝到 socket 缓冲区中 , DMA 引擎会将数据直接从内核缓冲区拷贝到协议引擎中去 , 这样就避免了最后一次数据拷贝 。
程序员必知必会的零拷贝技术

文章插图
 

【程序员必知必会的零拷贝技术】


推荐阅读