在linux系统中实现零拷贝的方法

  介绍

在linux系统中实现零拷贝的方法?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

什么是linux系统

linux是一种免费使用和自由传播的类UNIX操作系统,是一个基于POSIX的多用户,多任务,支持多线程和多CPU的操作系统,使用linux能运行主要的UNIX工具软件,应用程序和网络协议。

<强>传统的数据传输方式

  很长一段时间内,数据拷贝的认识仅仅停留在应用程序层,实际上隐藏在背后的数据拷贝行为比想象的要多的多。在传输数据的时候,用户应用程序需要分配一块合适大小的缓冲区来存放需要传输的数据。用户从应用程序中读取数据,然后发送出去,只需要两个系统调用读、写即可完成数据传输工作,应用程序并不知道这个数据传输过程中操作系统进行了多少次拷贝操作。某些情况下,这些数据拷贝操作会极大的降低数据传输的性能。(网卡、网络接口卡)

  传统的数据拷贝方式,如下图:
在linux系统中实现零拷贝的方法”>
  涉及的步骤:</p> <p>
  (1)阅读()调用引发从用户模式到内核模式的上下文切换(第一次切换),在内部,发出sys_read(或者同等内容)从设备中读取数据,直接内存读取直接内存访问(DMA)执行了拷贝(第一次拷贝),它从磁盘中读取内容,然后将他们存储到一个内核地址空间缓冲区中,</p> <p>
  (2)数据从读缓冲区拷贝到用户缓冲区(第二次拷贝)、阅读()调用返回。该调用返回引发内核模式到用户模式的切换(第二次切换)。现在数据被存储在用户空间缓冲区中,</p> <p>
  (3)发送()套接字调用引发用户模式到内核模式的上下文切换(第三次切换),数据再次被放置到内核地址空间缓冲区中(第三次拷贝)。这次放置的缓冲区与目标套接字关联;</p> <p>
  (4)发送()系统调用返回,从内核模式切换到用户模式(第四次切换),DMA引擎将数据从内核缓冲区传输到协议引擎(第四次拷贝)。</p> <p>
  DMA允许外围设备和贮存之间直接传输IO数据,DMA依赖于系统。每一种体系结构DMA传输不同,编程接口也不同。数据传输可以以两种方式触发:一种所软件请求数据,另一种所硬件异步传输。以阅读为例,它即采用第一种方式,其步骤如下:</p> <p>
  (1)进程调用读时,驱动程序分配一个DMA缓冲区,随后指示硬件传送它的数据,进程进入睡眠;</p> <p>
  (2)硬件将数据写入DMA缓冲区并在完成时产生一个中断;</p> <p>
  (3)中断处理程序获取输入数据,应答中断,最后唤醒进程,可以读取数据了。</p> <p>
  由此可见,在传统的数据传输中,系统方面总共进行了4次数据拷贝,4次上线文切换,这些都会对服务器性能造成很大影响。</p> <p> <强>零拷贝概述</强> </p> <p>
  简单的说,零拷贝是一种避免CPU将数据从一快存储拷贝到另外一块存储的技术。零拷贝技术的目标:</p> <p> </p> <p>
  #避免操作系统内核缓冲区之间进行数据拷贝操作,</p> <p>
  #避免操作系统内核和用户应用程序地址空间之间进行数据拷贝操作,</p> <p>
  #用户应用程序可以避免操作系统直接访问硬件存储;</p> <p>
  #数据传输尽量让DMA来处理。</p> <p> </p> <p>
  #避免不必要的系统调用和上下文切换。</p> <p>
  #需要拷贝的数据可以先缓存起来。</p> <p>
  #对数据进行的处理尽量让硬件来做。</p> <p> <强>零拷贝的实现方式分类</强> </p> <p> <强>直接IO </强> </p> <p>
  主要是通过减少操作系统内核缓冲区和应用程序地址空间数据拷贝次数,降低对文件读取和写入时带来的CPU使用和带宽的开销。对于某些页数的应用程序,比如说自缓冲应用程序来说,会是一个比较好的选择。如果要传输的数据量大,使用直接IO的方式进行数据传输,而不需要操作系统内核地址空间拷贝数据的参与,这将会提高性能。</p> <p>
  直接IO并不是所有的情况下都有效。设置直接IO的开销非常大,而且不能利用缓存IO的优势。直接IO的读操作会造成磁盘的同步读,执行进程需要在很长的时间才能执行完;而写操作会导致应用程序关闭缓慢。应用程序使用直接IO进行数据传输通常和异步IO结合使用。</p> <p>
  linux内核已经为快设备执行直接IO提供了支持,应用程序直接访问文件而不经过操作系统页高速缓冲存储器的时候,打开文件(open()系统调用)指定O_DIRECT标示符。<h2 class=在linux系统中实现零拷贝的方法