Zero Copy(零拷贝)

零拷贝技术减少了CPU在数据传输中的参与,通过DMA控制器实现高效的数据移动,例如sendfile系统调用在Linux中的应用。这种方式降低了上下文切换和内存拷贝次数,提高了系统效率。然而,传统的零拷贝仍存在从kernelbuffer到socketbuffer的拷贝,而GatherCopyDMA和mmap零拷贝进一步优化了这一过程,允许数据操作或减少额外拷贝。
摘要由CSDN通过智能技术生成

零拷贝基础

  • 零拷贝指的是,从一个存储区域到另一个存储区域的 copy 任务没有 CPU 参与。
    • 零拷贝通常用于网络文件传输,
      • 减少 CPU 消耗 和内存带宽占用,
      • 减少 用户空间 与 CPU 内核空间 的拷贝过程,
      • 减少 用户上下文 与 CPU 内核上下文 间的切换,
      • 提高系统效率。
  • 空间
    • 用户空间指的是用户可操作的内存缓存区域,
    • CPU 内核空间是指仅 CPU 可以操作的寄存器缓存及内存缓存区域。
  • 上下文
    • 用户上下文指的是用户状态环境,
    • CPU 内核上下文指的是 CPU 内核状态环境。
  • 零拷贝需要 DMA 控制器的协助。
    • DMA,Direct Memory Access,直接内存存取,是 CPU 的组成部分,其可以在 CPU 内核(算术逻辑运算器 ALU 等)不参与运算的情况下将数据从一个地址空间拷贝到另一个地址空间。

传统拷贝方式

  • 下面均以“将硬盘中的一个文件通过网络发送出去”的过程为例,详细分析不同拷贝方式的实现细节。

实现细节

  • 首先通过应用程序的 read()方法将文件从硬盘读取出来,然后再调用 send()方法将文件发送出去。

总结

  • 该拷贝方式共进行了 4 次用户空间与内核空间的上下文切换(1、4、5、7),以及 4 次数据拷贝(3、4、5、6),其中两次拷贝存在 CPU 参与(4、5)。
  • 发现一个很明显的问题:应用程序的作用仅仅就是一个数据传输的中介,最后将 Kernel buffer 中的数据传递到了 socket buffer。显然这是没有必要的。所以就引入了零拷贝。

零拷贝方式

实现细节

  • Linux 系统(CentOS 6 及其以上版本)对于零拷贝是通过 sendfile 系统调用实现的。

总结

  • 该拷贝方式共进行了 2 次用户空间与内核空间的上下文切换(1、6),以及 3 次数据拷贝(3、4、5),但整个拷贝过程均没有 CPU 的参与,这就是零拷贝。
  • 这里还存在一个问题: kernel buffer 到 socket buffer 的拷贝需要吗? kernel buffer 与 socket buffer 有什么区别呢?
    • DMA 控制器所控制的拷贝过程有一个要求,数据在源头的存放地址空间必须是连续的。
      • kernel buffer 中的数据无法保证其连续性,所以需要将数据再拷贝到 socket buffer, socket buffer 可以保证了数据的连续性。
  • 这个拷贝过程能否避免呢?
    • 可以,只要主机的 DMA 支持 Gather Copy 功能,就可以避免由 kernel buffer 到 socket buffer 的拷贝。

Gather Copy DMA 零拷贝方式

  • 由于该拷贝方式是由 DMA 完成,与系统无关,所以只要保证系统支持 sendfile 系统调用功能即可。

实现细节

  • 该方式中没有数据拷贝到 socket buffer,取而代之的是将 kernel buffer 中的数据描述信息写到了 Socket buffer 中。
    • 数据描述信息包含了两方面的信息: Kernel buffer 中数据的地址及偏移量。

总结

  • 该拷贝方式共进行了 2 次用户空间与内核空间的上下文切换(1、6),以及 2 次数据拷贝(3.5),整个拷贝过程均没有 CPU 参与。
  • 该拷贝方式的系统效率是高了,但与传统相比,也存在有不足。
    • 传统拷贝中 User buffer中存有数据,因此应用程序能够对数据进行修改等操作;零拷贝中的 user buffer 中没有了数据,所以应用程序无法对数据进行操作了。
    • Linux 的 mmap 零拷贝解决了这个问题。

mmap 零拷贝

  • mmap 零拷贝是对零拷贝的改进。
  • 当然,若当前主机的 DMA 支持 Gather Copy,mmap同样可以实现 Gather Copy DMA 的零拷贝。

实现细节

  • 该方式与零拷贝的唯一区别是,应用程序与内核共享了 Kernel buffer。
  • 由于是共享,所以应用程序就可以操作该 buffer 了。当然,应用程序对于 Kernel buffer 的操作,就会引发用户空间与内核空间的相互切换。

总结

  • 该拷贝方式共进行了 4 次用户空间与内核空间的上下文切换(1、共享Kernel buffer时user修改数据触发、6),以及 2 次数据拷贝(3、5),并且整个拷贝过程均没有 CPU 的参与。
  • 虽然较之前面的零拷贝增加了两次上下文切换,但应用程序可以对数据进行修改了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值