zoukankan      html  css  js  c++  java
  • 零拷贝

    问题 :

    • 零拷贝解决的是什么问题
    • 零拷贝的本质是什么
      文章部分知识来自参考链接中朱大的文章,半原创

    概述

      假如有以下场景:你需要发送一张图片给某个朋友,那么选择好图片后(read),建立连接发送。(write)

    read(file, tmp_buf, len);
    write(socket, tmp_buf, len);
    
    

      这个过程可以见下图
    1297993-20190929142438468-1914826245.png
      可以看到共4个步骤 :

    1. 调用read的时候,文件A从磁盘拷贝kernel模式下 (read)
    2. CPU控制将 kernel 模式数据拷贝到user模式下 (read)
    3. 调用 write时,先将user模式下的内容拷贝到kernel模式下 (write)
    4. 最后将kernel 模式下的socket buffer 拷贝到网卡设备中传输 (write)
        可以看到1到4中,要是网卡设备直接磁盘中拿到数据直接发送就不用2,3步骤中的拷贝了,即是磁盘数据 -> kernel模式下内存数据 -> 网卡设备发送

    Zero Copy

      零拷贝是如何工作的呢?

    1. transferTo()方法使得文件A的内容直接拷贝到一个read buffer(kernel buffer)中;
    2. 然后数据(kernel buffer)拷贝到socket buffer中。
    3. 最后将socket buffer中的数据拷贝到网卡设备(protocol engine)中传输;
      这显然是一个伟大的进步:这里把上下文的切换次数从4次减少到2次,同时也把数据copy的次数从4次降低到了3次。
      1297993-20190929145808455-596176468.png

    进阶

      我们看到 socket buffer 那里的复制要是可以提高就好了,Linux2.4 以后进行了优化,

    1. 将文件拷贝到kernel buffer中;
    2. 向socket buffer中追加当前要发生的数据在kernel buffer中的位置和偏移量;
    3. 根据socket buffer中的位置和偏移量直接将kernel buffer的数据copy到网卡设备(protocol engine)中;
        采用追加的方式,那样就不用每次都进行拷贝。
      1297993-20190929150127927-107816186.png

    概述

      整个过程就像这样子。
    1297993-20190929145517667-770207685.png

    参考资料

  • 相关阅读:
    Python学习笔记之操作yalm
    Python学习笔记之多线程
    Python学习笔记之网络编程
    Python学习笔记之面对象与错误处理
    Python学习笔记之装饰器
    Python学习笔记之内置模块
    Python学习笔记之函数与正则
    PAT甲级1049. Counting Ones
    PAT甲级1045. Favorite Color Stripe
    PAT甲级1034. Head of a Gang
  • 原文地址:https://www.cnblogs.com/Benjious/p/11608012.html
Copyright © 2011-2022 走看看