着信パケットを処理する際の Linux カーネルのオーバーヘッドを回避し、代わりにユーザー空間から直接パケットを取得したいとします。私は少しグーグルで調べましたが、発生する必要があるのは、いくつかのソケットオプションで生のソケットを使用することだけのようです。これは事実ですか?それとも、これよりも複雑ですか?もしそうなら、このようなものを実装するために何をグーグルまたは参照できますか?
1 に答える
カーネル バイパスを使用したネットワーキングには多くの手法があります。
まず、同じマシン上の別のプロセスにメッセージを送信する場合、カーネルにジャンプせずに共有メモリ領域を介して送信できます。
カーネルを介さずにネットワークを介してパケットを渡すことは、より興味深いものであり、ユーザー メモリに直接アクセスできる特殊なハードウェアを必要とします。この考え方は RDMA と呼ばれます。
これが機能する 1 つの方法を次に示します (これが InfiniBand ハードウェアの機能です)。アプリケーションは、メモリ バッファーを RDMA ハードウェアに登録します。このバッファは物理メモリに固定されています。これは、スワップ アウトが明らかに悪いためです (ハードウェアが物理メモリ領域に書き込みを続けるため)。制御領域もユーザー空間メモリーにマップされます。アプリケーションは、バッファーを使用してメッセージを送受信する準備ができると、制御領域にコマンドを書き込みます。ハードウェアは、一方の端で登録済みバッファからデータを取得し、もう一方の端で別の登録済みバッファに配置します。
明らかに、これは低レベルすぎるため、RDMA ハードウェアのプログラミングを容易にする抽象化があります。OFED 動詞は、そのような抽象化の 1 つです。
InfiniBand ソフトウェア スタックには、さらに興味深い点が 1 つあります。それは、既存のアプリケーションとの互換性のために使用される Sockets Direct Protocol (SDP) です。これは、標準ソケット API 呼び出しを IB 動詞に変換する LD_PRELOAD シムを挿入することによって機能します。
InfiniBand は、私が最もよく知っているものです。RoCE/iWARP ハードウェアは、プログラマーの観点からは非常に似ていますが、InfiniBand とは異なるトランスポートを使用します (iWarp ではオフロード エンジンを使用する TCP、RoCE ではイーサネットを使用します)。RDMA への他のアプローチもあります (Quadrics など)。