前言零拷贝(英语:Zero-copy)技术是指计算机执行操作时,CPU不需要先将数据从某处内存复制到另一个特定区域。这种技术通常用于通过网络传输文件时节省CPU周期和内存带宽。

零拷贝操作减少了在用户空间与内核空间之间切换模式的次数。

举例来说,如果要读取一个文件并通过网络发送它,传统方式下如下图,传统的I/O操作进行了4次用户空间与内核空间的上下文切换,以及4次数据拷贝。其中4次数据拷贝中包括了2次DMA拷贝和2次CPU拷贝。通过零拷贝技术完成相同的操作,减少了在用户空间与内核空间交互,并且不需要CPU复制数据。

linux中零拷贝技术

Linux系统的“用户空间”和“内核空间”

从Linux系统上看,除了引导系统的BIN区,整个内存空间主要被分成两个部分:内核空间(Kernel space)、用户空间(User space)。

“用户空间”和“内核空间”的空间、操作权限以及作用都是不一样的。

内核空间是Linux自身使用的内存空间,主要提供给程序调度、内存分配、连接硬件资源等程序逻辑使用;用户空间则是提供给各个进程的主要空间。

用户空间不具有访问内核空间资源的权限,因此如果应用程序需要使用到内核空间的资源,则需要通过系统调用来完成:从用户空间切换到内核空间,然后在完成相关操作后再从内核空间切换回用户空间。

Linux 中零拷贝技术的实现方向直接 I/O:对于这种数据传输方式来说,应用程序可以直接访问硬件存储,操作系统内核只是辅助数据传输。这种方式依旧存在用户空间和内核空间的上下文切换,但是硬件上的数据不会拷贝一份到内核空间,而是直接拷贝至了用户空间,因此直接I/O不存在内核空间缓冲区和用户空间缓冲区之间的数据拷贝。

在数据传输过程中,避免数据在用户空间缓冲区和系统内核空间缓冲区之间的CPU拷贝,以及数据在系统内核空间内的CPU拷贝。本文主要讨论的就是该方式下的零拷贝机制。

copy-on-write(写时复制技术):在某些情况下,Linux操作系统的内核空间缓冲区可能被多个应用程序所共享,操作系统有可能会将用户空间缓冲区地址映射到内核空间缓存区中。当应用程序需要对共享的数据进行修改的时候,才需要真正地拷贝数据到应用程序的用户空间缓冲区中,并且对自己用户空间的缓冲区的数据进行修改不会影响到其他共享数据的应用程序。所以,如果应用程序不需要对数据进行任何修改的话,就不会存在数据从系统内核空间缓冲区拷贝到用户空间缓冲区的操作。

mmap1

2buf = mmap(diskfd, len);

write(sockfd, buf, len);

应用程序调用mmap(),磁盘上的数据会通过DMA被拷贝的内核缓冲区,接着操作系统会把这段内核缓冲区与应用程序共享,这样就不需要把内核缓冲区的内容往用户空间拷贝。应用程序再调用write(),操作系统直接将内核缓冲区的内容拷贝到socket缓冲区中,这一切都发生在内核态,最后,socket缓冲区再把数据发到网卡去。

使用mmap替代read很明显减少了一次拷贝,当拷贝数据量很大时,无疑提升了效率。但是使用mmap是有代价的。当你使用mmap时,你可能会遇到一些隐藏的陷阱。例如,当你的程序map了一个文件,但是当这个文件被另一个进程截断(truncate)时, write系统调用会因为访问非法地址而被SIGBUS信号终止。SIGBUS信号默认会杀死你的进程并产生一个coredump,如果你的服务器这样被中止了,那会产生一笔损失。

当然也有办法解决,本文忽略解决办法。

sendfile1ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);

sendfile实现的零拷贝I/O只使用了2次用户空间与内核空间的上下文切换,以及3次数据的拷贝。其中3次数据拷贝中包括了2次DMA拷贝和1次CPU拷贝。

splice

sendfile只适用于将数据从文件拷贝到套接字上,限定了它的使用范围。Linux在2.6.17版本引入splice系统调用,用于在两个文件描述符中移动数据:

1

2

3#define _GNU_SOURCE /* See feature_test_macros(7) */

#include

ssize_t splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, unsigned int flags);

java中如何使用零拷贝

DMA简介

io读写的方式:中断,DMA

DMA 直接内存存取,是允许外设组件将I/O数据直接传送到主存储器中并且传输不需要CPU的参与,以此将CPU解放出来去完成其他的事情。,相较于中断方式,减少cpu中断次数,不用cpu拷贝数据。

主要流程如下:

用户进程发起数据读取请求

系统调度为该进程分配cpu

cpu向DMA发送io请求

用户进程等待io完成,让出cpu

系统调度cpu执行其他任务

数据写入至io控制器的缓冲寄存器

DMA不断获取缓冲寄存器中的数据(需要cpu时钟)

传输至内存(需要cpu时钟)

所需的全部数据获取完毕后向cpu发出中断信号

参考

linux零拷贝实现程序,浅析零拷贝技术相关推荐

  1. 深入剖析Linux IO原理和几种零拷贝机制的实现

    本文来说下Linux IO原理和几种零拷贝机制的实现 文章目录 概述 物理内存和虚拟内存 物理内存 虚拟内存 内核空间和用户空间 内核空间 用户空间 Linux的内部层级结构 Linux I/O读写方 ...

  2. linux系统文件复制过程时长,Linux系统I/O操作与零拷贝

    Linux系统I/O Linux中传统的I/O操作是一种缓存I/O,I/O过程中产生的数据传输通常需要在缓冲区中进行多次拷贝.当应用程序需要访问某个数据(read()操作)时,操作系统会先判断这块数据 ...

  3. 零拷贝、如何实现零拷贝、大文件如何传输

    9.零拷贝 9.1.为什么要有DMA技术? 1.在没有 DMA 技术前,I/O 的过程: CPU 发出对应的指令给磁盘控制器,然后返回: 磁盘控制器收到指令后,于是就开始准备数据,会把数据放⼊到磁盘控 ...

  4. linux处理除零异常,linux – 如何在x86程序集中使用中断来触发被零除错误异常?...

    我试图理解x86程序集中的中断. 我试图触发零除错误,它对应于代码0. int $0 我期待它具有与除以零相同的行为. movl $0, %edx # dividend movl $0, %eax # ...

  5. 八零后高薪程序员感慨中年危机,月薪五万多,想要跳槽没地方!

    高薪也有高薪的烦恼,意味着跳槽的机会也变少了.就像金字塔的顶端一样,越往上走,机会也就越少了,这在程序员圈子比较普遍.月薪三万以下随便跳槽,能开得起这样薪资的公司很多,但如果薪资超过三万,机会就变得很 ...

  6. Java黑皮书课后题第3章:3.7(金融应用:整钱兑零)修改程序清单2-10,使之只显示非零的币值单位,用单词的单数形式显示一个单位,复数形式显示多于一个的单位的值

    3.7(金融应用:整钱兑零)修改程序清单2-10,使之只显示非零的币值单位,用单词的单数形式显示一个单位,复数形式显示多于一个的单位的值 题目 题目概述 程序清单2-10(非本题代码) 破题/思路:这 ...

  7. .NET Core 小程序开发零基础系列(2)——小程序服务通知(模板消息)

    基于上一篇文件".NET Core 小程序开发零基础系列(1)--开发者启用并校验牵手成功"的反映,个人觉得效果很不错,大家对公众号开发还是有很大需求的,同时也收到了很多同学的问题 ...

  8. 小程序获取头像试试水 02《 程序员变现指南之 微信QQ 小程序 真的零基础开发宝典》

    本系列教程是针对粉丝的变现教程,还不是粉丝的可以关注我并且到社区:https://bbs.csdn.net/topics/603436232 进行打卡,不是老粉的也可以获取最终的技术变现学习,最终还有 ...

  9. 小程序的 HelloWord 01《 程序员变现指南之 微信QQ 小程序 真的零基础开发宝典》

    本系列教程是针对粉丝的变现教程,还不是粉丝的可以关注我并且到社区:https://bbs.csdn.net/topics/603436232 进行打卡,不是老粉的也可以获取最终的技术变现学习,最终还有 ...

最新文章

  1. NLPIR 分词准确率接近98.23%
  2. 解决cv2.findContours返回值too many values to unpack (expected 2)的问题
  3. 山石网科SG-6000-E5560配置SSL ***实例
  4. c/c++ 重载运算符 函数调用运算符
  5. 50道Java集合经典面试题
  6. 代码自动生成工具的补充
  7. AI实战分享 | 基于CANN的辅助驾驶应用案例
  8. java netty modbus协议接收iot数据
  9. 【论文解读】结合概率图模型和神经网络做图片问答
  10. 微信小程序登陆注册功能实现
  11. PCB layout的基本原则
  12. pycharm社区版创建flask项目
  13. 二维码的原理竟如此简单,第一次有人说的这么明白
  14. Web开发——Photoshop(PSD格式截取)
  15. python:在指定范围内按学号随机生成座位顺序,并分行输出
  16. JavaScript高级编程设计(第三版)——第四章:变量作用域和内存问题
  17. 机器人旋转关节非线性摩擦辨识
  18. 2-3查找树-树-数据结构和算法(Java)
  19. RabbitMQ之集群管理
  20. 吃豆腐”与“吃醋”的幽默来历

热门文章

  1. Anaconda3环境安装tensorflow2.0 python3.7使用spyder
  2. html5 随机抽签,基于JS实现的随机数字抽签实例
  3. 闲鱼项目如何操作?日收入1000+详细讲解!
  4. 测试同学都应该知道的断言知识...
  5. python中字典已经enumerate简单使用
  6. 在腾讯工作要不要感恩
  7. React项目,从详情页返回列表页时,保存数据并返回到原来的位置
  8. 最易懂的闪电网络Lightning Network的简介
  9. packer学习—用Docker构建器构建docker镜像
  10. 元素class类名的添加和删除之classList