ゼロコピーを示しています

オリジナルリンク:https://www.jianshu.com/p/8c6b056f73ce

伝統的なIOは、読み取りと書き込み

ターミナルIOおよびDMA:伝統的なIOは、2つの方法でお読みください。それぞれの作品は以下の通り。

1.1 IO割り込み原理

 

 

次のように全体のプロセスは次のとおりです。

  • 1.ユーザー・プロセスの呼び出しは、オペレーティングシステムの問題IO要求へのシステムコールを読んで、独自のメモリバッファにデータを読み込むように要求。遮断状態に身。
  • オペレーティングシステムの後2.リクエスト、さらにディスクIO要求を受信します。
  • 3.ディスクドライブは、カーネルのIO要求、ドライブバッファにディスクから読み出されたデータを受信します。このとき、CPUを占有しません。ドライブはバッファを読んでいるときに一杯になると、バッファ自身を知らせるカーネルを開始するための割り込み信号がいっぱいです。
  • 4.カーネルの割り込みは、カーネルバッファへのディスクドライブにデータバッファをコピーするために使用されたCPU時間を受信します。
  • カーネルバッファのデータ読み出し要求をユーザデータよりも小さい場合5、ステップ3、ステップ4で繰り返される、カーネルバッファのデータに十分なまでこれまで。
  • 6.データは、システムコールから戻ると、ユーザバッファにカーネルバッファからコピーされます。タスクを完了します。

短所:ユーザーからのすべてのIO要求は、CPUが参加している必要があります。

1.2 DMA原則

 
  • 1.ユーザー・プロセスの呼び出しは、オペレーティングシステムの問題IO要求へのシステムコールを読んで、独自のメモリバッファにデータを読み込むように要求。遮断状態に身。
  • オペレーティング・システムは、要求を受信した後に2は、IOはさらにDMAを要求します。そして、CPUが生きるために何かをやらせます。
  • 3.DMAさらにIOは、ディスクに要求します。
  • 4.ディスクドライブはDMA IO要求、ドライブバッファにディスクから読み出されたデータを受信します。ドライブは、バッファがいっぱいになる読んでいる場合は、DMAへの割り込み信号は、そのバッファの通知を開始しましたがいっぱいです。
  • ディスクドライブの受信信号、カーネルバッファ内のデータバッファのディスクドライブのコピーを4.DMA。このとき、CPUを占有しません。この時間は限りデータは、ユーザーのアプリケーションデータを読み取るためにカーネルバッファ未満であると、カーネルは常に十分な、これまでのカーネル・データ・バッファまで、ステップ4とステップ3を繰り返します。
  • DMAは、十分なデータを読み込むときに5.は、それが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读写一样的问题。系能其实并没有什么大的提升。

おすすめ

転載: www.cnblogs.com/fswhq/p/11517726.html