問題タブ [zero-copy]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - Linux の splice() 関数を使用してファイルを別のファイルにコピーするにはどうすればよいですか?
splice() に関する別の質問があります。私はそれを使用してファイルをコピーしたいと考えており、splice の Wikipedia ページの例のように、パイプで結合された 2 つの splice 呼び出しを使用しようとしています。あるファイルから最初の 32K バイトを読み取り、別のファイルに書き込むだけの簡単なテスト ケースを作成しました。
これを実行すると、入力ファイルは正しく読み込まれているように見えますが、2 番目の splice 呼び出しは EINVAL で失敗します。ここで私が間違っていることを知っている人はいますか?
ありがとう!
terminology - 用語:「ゼロコピー」の反対?
Linux のゼロコピー システム コールである sendfile() を使用するように変換したコードのベンチマークを行っています。sendfile() が置き換える従来の read()/write() ループの用語は何ですか? つまり、私たちのレポートでは、「zerocopy は X ミリ秒、??? は Y ミリ秒」と言いたいのです。どの単語/フレーズを使用すればよいですか?
c - Linux の splice(2) によるスプライシングをサポートしているのはどのファイル システムですか?
システムコールのマニュアルページには、splice
失敗splice
する可能性があり、次の場合に設定さerrno
れると記載されていEINVAL
ます。
ターゲット ファイル システムはスプライシングをサポートしていません。どちらの記述子もパイプを参照していません。またはシークできないデバイスに指定されたオフセット
スプライシングをサポートするファイル システムはどれですか?
c - 読み取り可能なファイル記述子がパイプの読み取り端であるかどうかの判別
を使用して、データをファイル記述子(通常のファイル、charまたはblockデバイス、FIFO、またはで開くことができるもの)splice
にゼロコピーしたいと思います。を使用するには、fromファイル記述子またはtoファイル記述子のいずれかがパイプの適切な端である必要があるため、通常、プログラマーが非パイプから非パイプにデータをゼロコピーする場合は、中間バッファーとして機能するパイプが作成されます。 -パイプ。ただし、がすでにパイプの読み取り端である場合は、その手順をスキップして、他のファイル記述子から直接スプライスを試みることができます。したがって、パイプの読み取り端であるかどうかを判断できるようにしたいと思います。STDIN_FILENO
open
splice
STDIN_FILENO
STDIN_FILENO
STDIN_FILENO
STDIN_FILENO
パイプの読み取り側かどうかを判断できるLinuxシステムコールはありますか?
c - sendfile() を使用すると、in_fd がいつ EOF になるかを知ることができますか?
Linux システム コール のマニュアル ページをsendfile
読んで、呼び出し元のプログラムがいつin_fd
EOFにあるかを知ることができるかどうか疑問に思っています。おそらく、これは戻り値 0 によって通知される可能性がありますが、これは戻り値 0 が実際に何を意味するのかという問題につながります。sendfile
のような場合write
、戻り値 0 は 0 バイトがコピーされたことを意味します。しかし、sendfile
が のような場合read
、戻り値 0 は EOF を意味します。を使用するためにからin_fd
にコピーするバイト数を事前に知っておく必要がありますか? 0 を返すとはどういう意味ですか?out_fd
sendfile
sendfile
tcp - パイプから TCP バッファリングへの splice() ?
linuxquestions.org からの xpost、申し訳ありません...
単純なプロキシが splice() を使用することでメリットが得られるかどうかを確認する小さなテスト プログラムを作成しましたが、パイプから TCP ソケットに接続したデータをソケットの反対側から読み取るには、常に 200 ミリ秒かかります。
これをテストするPerlプログラムは次のとおりです。
次に、strace 出力のサンプルを示します。
~200ms の read(9,...) 呼び出しに注意してください。「\n」を送信する行のコメントを外すと、遅延はありません。私は何を間違っていますか?ありがとう!
linux - 共有メモリの結果をゼロコピーしてプロセス間で通信しますか?
Linuxでカーネル2.6を使用してネットワークデーモンを作成しています。このデーモンには、 1つのプロデューサープロセスとN個のコンシューマープロセスがあり、データに変更を加えず、プロデューサーへの応答を作成しません。
プロデューサープロセスは、長さが数10バイトから数10 Kバイトまで変化するデータオブジェクトを生成するときはいつでも、データオブジェクトを1つの使用可能なコンシューマープロセスに渡す必要があります。
初めて、名前付き/名前なしのパイプを使用することを検討しました。ただし、それらはメモリコピーのオーバーヘッドになります。
- プロデューサーのユーザースペースバッファー--copy->カーネルスペースPIPEバッファー
- カーネルスペースPIPEバッファー--copy->コンシューマーのユーザースペースバッファー
プログラムは待ち時間の短い多数のピアで動作する可能性があるため、コピーオーバーヘッドは有害である可能性があります。そのため、mmap()でPOSIX共有メモリを使用することにしました。
POSIX共有メモリをmmap()で使用してプロセス間でデータを共有しても、PIPEとは異なり、メモリコピーが発生しないのではないかと思っています。
また、プロセス間でデータを共有する他の方法はありますが、結果はゼロコピーになりますか?プログラムは、最新バージョンのカーネルを搭載したLinuxで実行され、クロスプラットフォーム機能を備えている必要はない場合があります。
コンシューマー/プロデュースごとにスレッドを生成/実行するのではなく、設計上の問題のためにプロセスを実行することにしました。
返信ありがとうございます。
linux - vmsplice()とTCP
元のvmsplice()
実装では、パイプに収まる最大ページ数の2倍のユーザーランドバッファーがある場合、バッファーの後半でvmsplice()が成功すると、カーネルがバッファの前半。
しかし、それは結局のところ真実ではありませんでした。特にTCPの場合、カーネルページは反対側からACKを受信するまで保持されていました。これを修正することは将来の作業として残されたため、TCPの場合、カーネルはパイプからページをコピーする必要があります。
vmsplice()
ある種のこれに対処するオプションがありSPLICE_F_GIFT
ますが、問題は、カーネルから新しいページを効率的に取得する方法と、キャッシュのゴミ箱を減らす方法という、他の2つの問題を明らかにすることです。最初の問題は、mmapがカーネルにページをクリアすることを要求することであり、2番目の問題は、mmapがカーネルで派手なkscrubd機能を使用するかもしれないが、プロセスのワーキングセットを増やすことです(キャッシュトラッシング)。
これに基づいて、私はこれらの質問があります:
- ページの安全な再利用についてユーザーランドに通知するための現在の状態は何ですか?私は特にソケット(TCP)にsplice()されたページに興味があります。過去5年間に何かが起こりましたか?
- //
mmap
/ TCPサーバーでのゼロコピーの現在のベストプラクティスですか、それとも今日より良いオプションがありますか?vmsplice
splice
munmap
udp - Linux splice()がEINVAL( "無効な引数")を返す
splice( man 2 splice)を使用してデータをUDPソケットからファイルに直接コピーすることを試みています。残念ながら、splice()を最初に呼び出すとEINVALが返されます。
マニュアルページには次のように記載されています。
ただし、これらの条件はいずれも当てはまらないと思います。私はFedora15(カーネル2.6.40-4)を使用しているので、splice()はすべてのファイルシステムでサポートされていると思います。ターゲットファイルは、スプライスの最初の呼び出しでは無関係である必要がありますが、完全を期すために、を介して開いていopen(path, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR)
ます。どちらの呼び出しもパイプを使用し、どちらの呼び出しもNULL以外のオフセットを使用します。
これが私のサンプルコードです:
sock_fdは、次の擬似コードによって初期化されます。
おそらく関連しているのは、このコードスニペットがlibeventループ内で実行されていることです。libeventはepoll()を使用して、UDPソケットがホットかどうかを判別しています。
windows - ゼロコピーはWindowsOSに存在しますか?
このゼロコピーの記事を読んで、
ゼロコピーはWindowsOS(サーバー2003、2008、2008 R2)に存在しますか?