ネットワーク ドライバーは、転送を高速化するために既に DMA を使用しています。を発行するとwrite
、カーネルは物理メモリの連続ブロックを割り当て、ユーザー空間バッファからこのメモリにデータをコピーします。この段階で、カーネルは必要なすべてのイーサネットおよび TCP/IP ヘッダーをアタッチします。
次に、カーネルはネットワーク カードに DMA 要求を発行し、その物理メモリの場所からデータを取得して内部バッファにロードするように要求します。この時点で、write
システム コールが返されます。ネットワーク カードが完成すると (そしてデータがアダプタから出力されるようになると)、ネットワーク カードはカーネルに完了を通知します。
Linux では、ネットワーク ドライバーは通常シングル スレッドです (これにはいくつかの例外がありますが、複雑になります)。そのため、write
データを取得しようとしてドライバーが既にアクティブである場合、データはカーネル空間にコピーされますが、DMA 要求は実行されません。ネットワークドライバーが再び解放されるまで (DMA が完了したことがカーネルに次に通知されたときにトリガーされます)。
話の士気は、これはすでに機能しており、かなり高速であるということです。DMA を使用してアプリケーションを高速化するために何もする必要はなく、すでに処理されています。高速化できる唯一の部分は、カーネル空間バッファー内のコピーですが、これは実際のネットワーク転送よりもはるかに高速である (そして同時に実行できる) ため、スループットに違いはなく、レイテンシーのみに影響します。
注: 上記は場所によっては大幅に簡略化したものです。特定の部分についてさらに詳しく知りたい場合は、質問を編集してください。できる限りのことを行います。