• zero copy图解


    原文链接:https://www.jianshu.com/p/8c6b056f73ce

    1 传统的IO读写

    传统的IO读写有两种方式:IO终端和DMA。他们各自的原理如下。

    1.1 IO中断原理

     

    整个流程如下:

    • 1.用户进程调用read等系统调用向操作系统发出IO请求,请求读取数据到自己的内存缓冲区中。自己进入阻塞状态。
    • 2.操作系统收到请求后,进一步将IO请求发送磁盘。
    • 3.磁盘驱动器收到内核的IO请求,把数据从磁盘读取到驱动器的缓冲中。此时不占用CPU。当驱动器的缓冲区被读满后,向内核发起中断信号告知自己缓冲区已满。
    • 4.内核收到中断,使用CPU时间将磁盘驱动器的缓存中的数据拷贝到内核缓冲区中。
    • 5.如果内核缓冲区的数据少于用户申请的读的数据,重复步骤3跟步骤4,直到内核缓冲区的数据足够多为止。
    • 6.将数据从内核缓冲区拷贝到用户缓冲区,同时从系统调用中返回。完成任务。

    缺点:用户的每次IO请求,都需要CPU多次参与。

    1.2 DMA原理

     
    • 1.用户进程调用read等系统调用向操作系统发出IO请求,请求读取数据到自己的内存缓冲区中。自己进入阻塞状态。
    • 2.操作系统收到请求后,进一步将IO请求发送DMA。然后让CPU干别的活去。
    • 3.DMA进一步将IO请求发送给磁盘。
    • 4.磁盘驱动器收到DMA的IO请求,把数据从磁盘读取到驱动器的缓冲中。当驱动器的缓冲区被读满后,向DMA发起中断信号告知自己缓冲区已满。
    • 4.DMA收到磁盘驱动器的信号,将磁盘驱动器的缓存中的数据拷贝到内核缓冲区中。此时不占用CPU。这个时候只要内核缓冲区的数据少于用户申请的读的数据,内核就会一直重复步骤3跟步骤4,直到内核缓冲区的数据足够多为止。
    • 5.当DMA读取了足够多的数据,就会发送中断信号给CPU。
    • 6.CPU手动DMA的信号,知道数据已经准备好,于是将数据从内核拷贝到用户空间,系统调用返回。

    跟IO中断模式相比,DMA模式下,DMA就是CPU的一个代理,它负责了一部分的拷贝工作,从而减轻了CPU的负担。
    DMA的优点就是:中断少,CPU负担低。

    2 文件到网络场景的zero copy技术

    2.1 传统IO读写方式的问题

    在读取文件数据然后发送到网络这个场景中,传统IO读写方式的过程如下。

     

    由图可知,整个过程总共发生了四次拷贝和四次的用户态和内核态的切换。
    用户态和内核态的切换如下。借个网上的图。

     

    2.2 zero copy技术

     

    zero copy技术就是减少不必要的内核缓冲区跟用户缓冲区间的拷贝,从而减少CPU的开销和内核态切换开销,达到性能的提升。
    zero copy下,同样的读取文件然后通过网络发送出去,只需要拷贝三次,只发生两次内核态和用户态的切换。
    再次盗用一下别人的图。

     

    3 linux下的zero copy技术

    linux下的用来实现zero copy的常见接口由如下几个:

    • ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count)
    • long splice(int fdin, int fdout, size_t len, unsigned int flags);
      这两个接口都可以用来在两个文件描述符之间传输数据,实现所谓的zero copy。
      splice接口则要求两个文件描述符中至少要有一个是pipe。

    3.1 sendfile跟splice的局限性

    上面提到的用来实现零拷贝的sendfile和splice接口,仅限于文件跟文件,文件跟sock之间传输数据,但是没法直接在两个socket之间传输数据的。这就是sendfile和splice接口的局限性。
    如果要实现socket跟socket之间的数据直接拷贝,需要开辟一个pipe,然后调用两次splice。这样还是带来跟传统IO读写一样的问题。系能其实并没有什么大的提升。

  • 相关阅读:
    C# .NET5.0 平台介绍、演变
    ORA01034/ORA27101解决
    navicat无法连接虚拟机MySQL
    [原创]Windows下Google V8 javascript引擎编译
    CentOS 6.9安装MySQL5.5
    国内yum源
    【转】关于C++程序的编码问题
    VS C4819 编译错误解决方法
    Windows下Vundle安装
    vmware NAT 静态ip配置
  • 原文地址:https://www.cnblogs.com/fswhq/p/11517726.html
Copyright © 2020-2023  润新知