美文网首页
zero copy技术图解

zero copy技术图解

作者: 小怪兽狂殴奥特曼 | 来源:发表于2018-04-09 21:51 被阅读681次

    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读写一样的问题。系能其实并没有什么大的提升。

    相关文章

      网友评论

          本文标题:zero copy技术图解

          本文链接:https://www.haomeiwen.com/subject/yqlwhftx.html