本文是对参考文章重要部分的摘录,同时进行简单地总结。

零拷贝技术的相关背景知识

传统的 Linux 操作系统的标准 I/O 接口是基于数据拷贝操作的,即 I/O 操作会导致数据在操作系统内核地址空间的缓冲区和应用程序地址空间定义的缓冲区之间进行传输,这样做最大的好处是可以减少实际的物理磁盘 I/O 操作。但是数据传输过程中的数据拷贝操作却导致了极大的 CPU 开销,限制了操作系统有效进行数据传输操作的能力。

简单一点来说,零拷贝就是一种避免 CPU 将数据从一块存储拷贝到另外一块存储的技术。
零拷贝技术可以减少数据拷贝和共享总线操作的次数,消除传输数据在存储器之间不必要的中间拷贝次数,从而有效地提高数据传输效率。而且,零拷贝技术减少了用户应用程序地址空间和操作系统内核地址空间之间因为上下文切换而带来的开销。
针对操作系统中的设备驱动程序、文件系统以及网络协议堆栈而出现的各种零拷贝技术极大地提升了特定应用程序的性能,并且使得这些应用程序可以更加有效地利用系统资源。

为什么需要零拷贝技术

很多网络服务器都是基于客户端 - 服务器这一模型的。在这种模型中,客户端向服务器端请求数据或者服务;服务器端则需要响应客户端发出的请求,并为客户端提供它所需要的数据。随着网络服务的逐渐普及,video 这类应用程序发展迅速。当今的计算机系统已经具备足够的能力去处理 video 这类应用程序对客户端所造成的重负荷,但是对于服务器端来说,它应付由 video 这类应用程序引起的网络通信量就显得捉襟见肘了。举个例子来说,当数据“写”操作或者数据“发送”操作的系统调用发出时,操作系统通常都会将数据从应用程序地址空间的缓冲区拷贝到操作系统内核的缓冲区中去。操作系统这样做的好处是接口简单,但是却在很大程度上损失了系统性能,因为这种数据拷贝操作不单需要占用 CPU 时间片,同时也需要占用额外的内存带宽。

一般来说,一个 CPU 时钟周期可以处理一位的数据。举例来说,一个 1 GHz 的处理器可以对 1Gbit/s 的网络链接进行传统的数据拷贝操作,但是如果是 10 Gbit/s 的网络,那么对于相同的处理器来说,零拷贝技术就变得非常重要了。

Linux 中传统服务器进行数据传输的流程如下。
当应用程序需要访问某块数据的时候,操作系统内核会先检查这块数据是不是因为前一次对相同文件的访问而已经被存放在操作系统内核地址空间的缓冲区内,如果在内核缓冲区中找不到这块数据,Linux 操作系统内核会先将这块数据从磁盘读出来放到操作系统内核的缓冲区里去。如果这个数据读取操作是由 DMA 完成的,那么在 DMA 进行数据读取的这一过程中,CPU 只是需要进行缓冲区管理,以及创建和处理 DMA ,除此之外,CPU 不需要再做更多的事情,DMA 执行完数据读取操作之后,会通知操作系统做进一步的处理。Linux 操作系统会根据 read() 系统调用指定的应用程序地址空间的地址,把这块数据存放到请求这块数据的应用程序的地址空间中去,在接下来的处理过程中,操作系统需要将数据再一次从用户应用程序地址空间的缓冲区拷贝到与网络堆栈相关的内核缓冲区中去,这个过程也是需要占用 CPU 的。数据拷贝操作结束以后,调用 write() 系统调用时,数据会被打包,然后发送到网络接口卡上去,这个操作也可以通过DMA完成。在数据传输的过程中,应用程序可以先返回进而执行其他的操作。之后,在调用 write() 系统调用的时候,用户应用程序缓冲区中的数据内容可以被安全的丢弃或者更改,因为操作系统已经在内核缓冲区中保留了一份数据拷贝,当数据被成功传送到硬件上之后,这份数据拷贝就可以被丢弃。
物理磁盘 》 内核页缓存 》 应用程序缓冲区 》 内核协议栈缓冲区 》 物理网卡缓冲区,去掉两次 DMA 拷贝操作,CPU 还得参与两次拷贝操作。

有哪几种零拷贝技术

Linux 中的直接 I/O

直接 I/O 是相对于缓存 I/O 的。缓存 I/O 又被称作标准 I/O,大多数文件系统的默认 I/O 操作都是缓存 I/O。在 Linux 的缓存 I/O 机制中,操作系统会将 I/O 的数据缓存在文件系统的页缓存( page cache )中,也就是说,数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区拷贝到应用程序的地址空间。在缓存 I/O 机制中,DMA 方式可以将数据直接从磁盘读到页缓存中,或者将数据从页缓存直接写回到磁盘上,而不能直接在应用程序地址空间和磁盘之间进行数据传输,这样的话,数据在传输过程中需要在应用程序地址空间和页缓存之间进行多次数据拷贝操作,这些数据拷贝操作所带来的 CPU 以及内存开销是非常大的。
对于某些特殊的应用程序来说,避开操作系统内核缓冲区而直接在应用程序地址空间和磁盘之间传输数据会比使用操作系统内核缓冲区获取更好的性能,这就是直接 I/O 要解决的问题。直接 I/O 完全不需要 Linux 操作系统内核提供的页缓存的支持。但是直接 I/O 有时候也会对性能产生负面影响,所以应用程序使用直接 I/O 进行数据传输的时候通常会和使用异步 I/O 结合使用。
物理磁盘 》 应用程序缓冲区 》 物理网卡缓冲区。

针对数据传输不需要经过应用程序地址空间的零拷贝技术

有的时候,应用程序在数据进行传输的过程中不需要对数据进行访问,那么,将数据从 Linux 的页缓存拷贝到用户进程的缓冲区中就可以完全避免,传输的数据在页缓存中就可以得到处理。
在某些特殊的情况下,这种零拷贝技术可以获得较好的性能。Linux 中提供类似的系统调用主要有 mmap(),sendfile() 以及 splice()。
物理磁盘 》 内核页缓存 》 内核协议栈缓冲区 》 物理网卡缓冲区。

对应用程序地址空间和内核之间的数据传输进行优化的零拷贝技术

该零拷贝技术侧重于灵活地处理数据在用户进程的缓冲区和操作系统的页缓存之间的拷贝操作。这种方法延续了传统的通信方式,这算是对前两种技术的一个折中,但是更加灵活。在 Linux 中,该方法主要利用了写时复制技术。

写时复制是计算机编程中的一种优化策略,它的基本思想是这样的:如果有多个应用程序需要同时访问同一块数据,那么可以为这些应用程序分配指向这块数据的指针,在每一个应用程序看来,它们都拥有这块数据的一份数据拷贝,当其中一个应用程序需要对自己的这份数据拷贝进行修改的时候,就需要将数据真正地拷贝到该应用程序的地址空间中去,也就是说,该应用程序拥有了一份真正的私有数据拷贝,这样做是为了避免该应用程序对这块数据做的更改被其他应用程序看到。这个过程对于应用程序来说是透明的,如果应用程序永远不会对所访问的这块数据进行任何更改,那么就永远不需要将数据拷贝到应用程序自己的地址空间中去。
写时复制的最大好处就是可以节约内存。不过对于操作系统内核来说,写时复制增加了其处理过程的复杂性。

零拷贝技术概括

来自wikipedia

Zero-copy versions of operating system elements, such as device drivers, file systems, and network protocol stacks, greatly increase the performance of certain application programs and more efficiently utilize system resources.

Techniques for creating zero-copy software include the use of DMA-based copying and memory-mapping through an MMU. These features require specific hardware support and usually involve particular memory alignment requirements.

避免数据拷贝

  1. 避免操作系统内核缓冲区之间进行数据拷贝操作。
  2. 避免操作系统内核和用户应用程序地址空间这两者之间进行数据拷贝操作。
  3. 用户应用程序可以避开操作系统直接访问硬件存储。
  4. 数据传输尽量让 DMA 来做。

将多种操作结合在一起

  1. 避免不必要的系统调用和上下文切换。
  2. 需要拷贝的数据可以先被缓存起来。
  3. 对数据进行处理尽量让硬件来做。

参考:Zero-copyLinux 中的零拷贝技术,第 1 部分Linux 中的零拷贝技术,第 2 部分Linux 中直接 I/O 机制的介绍

Linux中的zero-copy技术的更多相关文章

  1. Linux 中的零拷贝技术,第 1 部分

    概述 本系列由两篇文章组成,介绍了当前用于 Linux 操作系统上的几种零拷贝技术,简单描述了各种零拷贝技术的实现,以及它们的特点和适用场景.本文是本系列文章的第一部分,主要是介绍一些零拷贝技术的相关 ...

  2. 【转】浅析Linux中的零拷贝技术

    本文探讨Linux中主要的几种零拷贝技术以及零拷贝技术适用的场景.为了迅速建立起零拷贝的概念,我们拿一个常用的场景进行引入: 引文## 在写一个服务端程序时(Web Server或者文件服务器),文件 ...

  3. [转帖]Linux 中的零拷贝技术,第 2 部分

    Linux 中的零拷贝技术,第 2 部分 https://www.ibm.com/developerworks/cn/linux/l-cn-zerocopy2/index.html   Linux 中 ...

  4. [转帖]Linux 中的零拷贝技术,第 1 部分

    Linux 中的零拷贝技术,第 1 部分 https://www.ibm.com/developerworks/cn/linux/l-cn-zerocopy1/index.html   引言 传统的 ...

  5. Linux 中的零拷贝技术,第 2 部分

    技术实现 本系列由两篇文章组成,介绍了当前用于 Linux 操作系统上的几种零拷贝技术,简单描述了各种零拷贝技术的实现,以及它们的特点和适用场景.第一部分主要介绍了一些零拷贝技术的相关背景知识,简要概 ...

  6. 浅析 Linux 中的零拷贝技术

    本文探讨Linux中 主要的几种零拷贝技术 以及零拷贝技术 适用的场景 .为了迅速建立起零拷贝的概念,我们拿一个常用的场景进行引入: 引文 在写一个服务端程序时(Web Server或者文件服务器), ...

  7. Linux中的零拷贝技术

    转载:https://www.jianshu.com/p/fad3339e3448 引文## 在写一个服务端程序时(Web Server或者文件服务器),文件下载是一个基本功能.这时候服务端的任务是: ...

  8. Linux中的零拷贝

    零拷贝 本文图片和一些内容均来自后面的参考,非原创只是把文章中的一些关键内容整理一下,算作是一个学习笔记. 传统的I/O操作 传统的IO操作是用户应用程序只是需要调用两个系统调用 read() 和 w ...

  9. 理解 Linux 网络栈(2):非虚拟化Linux 环境中的 Segmentation Offloading 技术

    本系列文章总结 Linux 网络栈,包括: (1)Linux 网络协议栈总结 (2)非虚拟化Linux环境中的网络分段卸载技术 GSO/TSO/UFO/LRO/GRO (3)QEMU/KVM + Vx ...

随机推荐

  1. git分支综述

    对git不是很熟悉,有个问题要弄清楚一下. 假如远程仓库有 dev 和 master 两个分支,master 作为一个稳定版分支,可用于直接发布产品,日常的开发则 push 到 dev 分支,那我本地 ...

  2. JAVA基础--异常

    异常的分类: 1. Throwable: 根类 1) Error:系统错误, 由java虚拟机生成并抛出, 无法处理 2) Exception: 所有异常类的父类, 可以处理的错误, 可以catch到 ...

  3. c语言学习基础:[1]开发工具介绍

    标签:c语言 1 2 3 4 分步阅读 学习编程语言的童鞋们一开始接触到的最多的估计就是C语言了,其次才是什么java.c++等,可以说学习c语言是我们走向编程世界的一座桥梁,学好它,对于我们学习和研 ...

  4. 推荐!国外程序员整理的Java资源大全

    http://www.importnew.com/14429.html 本文由 ImportNew - 唐尤华 翻译自 github akullpp.欢迎加入翻译小组.转载请见文末要求. 构建 这里搜 ...

  5. Java6.0中Comparable接口与Comparator接口详解

    Java6.0中Comparable接口与Comparator接口详解 说到现在,读者应该对Comparable接口有了大概的了解,但是为什么又要有一个Comparator接口呢?难道Java的开发者 ...

  6. RunLoop基础

    序言 RunLoop一直是比较高级而又比较神秘的技术,一直以来都没有深入去阅读过苹果给出的官方文档.本篇文章就讲讲苹果官方文档中所介绍的RunLoop,再加上其开源性,让我们一起深入去研究其特性及与线 ...

  7. (中等) POJ 2948 Martian Mining,DP。

    Description The NASA Space Center, Houston, is less than 200 miles from San Antonio, Texas (the site ...

  8. STM32启动模式及API(转)

    源:STM32启动模式及API 我们玩ARM9,一般都是在内存里调试程序,速度飞快.STM32下也可以这样,虽说现在的flash寿命已经很长了,但flash中调试烧录程序还是一个很慢的过程,有时候程序 ...

  9. tableview的reloadData应注意

    http://blog.csdn.net/ouyangtianhan/article/details/7835041 http://stackoverflow.com/questions/160715 ...

  10. Android L(5.0)源码之图形与图像处理之动画——Frame、Tween、属性动画、SurfaceView

    工作中暂时还没涉及到,暂时先不总结