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

    一、问题

      传统的Linux io操作,直接与io交互的话,首先得寻址,这个寻址是个很耗时的过程。为了减少与磁盘的io,加了一个page cache层,也就是os cache。如果page cache有的话就不需要到磁盘里找了,直接返回,这个速度就很快了。如果没有再到磁盘里查询,进行读写。那么一次io的操作就是:

      

         1.从磁盘文件中拷贝到内核中的页缓存。这步是DMA copy的,发生第一次copy。

      2.从页缓存拷贝到用户空间缓存里,也就是应用程序对应的内存空间里。这步是CPU copy的,发生第二次copy,而且从内核态切换到用户态,发生了第一次切换。

      3.从用户空间缓存拷贝到socket缓存区。这步是CPU copy的,发生第三次copy,从用户态切换到内核态,又发生了一次切换。   

      4.从socket缓冲区拷贝到网络中。这步是DMA copy的,发生第四次copy。      

      可以看到一共发生了4次拷贝,其中cpu 参与了两次拷贝,而且用户态和内核态也发生了多次上下文切换,非常的耗cpu资源。

    二、定义

      为了避免拷贝对cpu的压力,我们可以通过减少不必要的拷贝来进行优化。所谓的零拷贝,并不是不发生一次拷贝,而是减少不必要的拷贝去进行优化。

    三、方法

      1.mmap

      

       应用程序调用mmap,从磁盘文件DMA copy到页缓存中,用户空间缓存与页缓存共享这部分内存,所以就不需要从页缓存拷贝到用户空间中了。然后直接通过CPU copy到Socket缓冲区中,再DMA copy到网络中。可以发现,少了一次CPU copy, 而且没有了用户态和内核态的上下文切换了。

      2.sendfile

      

       Linux从2.1版内核开始引入了sendfile,直接从页缓存拷贝到socket缓存中。

      

    #include<sys/sendfile.h>
    ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count)

      从out_fd到in_fd传输数据,但是页缓存到socket缓存还是发生了一次CPU copy的,这步不是必要的,也可以进行优化。

       sendfile通过DMA 引擎进行优化,只是将将文件描述符传输给socket缓存,数据直接从页缓存发送到网络中。

     缺点:只适用与将文件拷贝到套接字上。

     3.splice

      Linux在2.6.17版本引入splice系统调用,用于在两个文件描述符中移动数据:

    #define _GNU_SOURCE         /* See feature_test_macros(7) */
    #include <fcntl.h>
    ssize_t splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, unsigned int flags);

      缺点:至少有一个文件描述符为管道。

    参考文档:https://mp.weixin.qq.com/s/7IT10kFfg8bxchaN_n-GEg

  • 相关阅读:
    hihoCoder #1062 : 最近公共祖先·一
    hihoCoder #1050 : 树中的最长路
    hihoCoder #1049 : 后序遍历
    108 Convert Sorted Array to Binary Search Tree 将有序数组转换为二叉搜索树
    107 Binary Tree Level Order Traversal II 二叉树的层次遍历 II
    106 Construct Binary Tree from Inorder and Postorder Traversal 从中序与后序遍历序列构造二叉树
    105 Construct Binary Tree from Preorder and Inorder Traversal 从前序与中序遍历序列构造二叉树
    104 Maximum Depth of Binary Tree 二叉树的最大深度
    102 Binary Tree Level Order Traversal 二叉树的层次遍历
    101 Symmetric Tree 判断一颗二叉树是否是镜像二叉树
  • 原文地址:https://www.cnblogs.com/ITyannic/p/12436736.html
Copyright © 2011-2022 走看看