IPCパフォーマンス:名前付きパイプとソケット


114

名前付きパイプはソケットIPCより速いと誰もが言うようです。彼らはどれくらい速いですか?ソケットを使用したいのは、双方向通信が可能で非常に柔軟性があるためです。ただし、速度がかなり高い場合は、柔軟性よりも速度を選択します。


10
あなたの走行距離は異なります。:)目的のアプリケーションの一般的な使用をプロファイリングし、2つの中から適切なものを選択します。次に、匿名パイプ、他のドメインおよびファミリのソケット、セマフォ、共有メモリまたはメッセージキュー(SysVおよびPOSIX)、データワードを含むリアルタイムシグナルなどをプロファイルします。 pipe(2)(er mkfifo(3)、?)が勝者かもしれませんが、試すまでわかりません。
ピルクロー2009

2
SysVメッセージキューFTW!彼らが速いかどうかは分かりませんが、私は彼らのためのソフトスポットを持っています。
トムアンダーソン

4
この場合の「速度」とは何ですか?全体的なデータ転送速度は?またはレイテンシ(最初のバイトがレシーバーに到達するまでの時間)?高速のローカルデータ転送が必要な場合は、共有メモリに勝るものはありません。レイテンシが問題になる場合は、質問がさらに面白くなります...
Ian Ni-Lewis

回答:


64

ソケットからパイプに変更できるように、IPCメカニズムを慎重に分離して、最初に簡単なパスをとることをお勧めしますが、私は間違いなく最初にソケットを使用します。先制的に最適化する前に、IPCパフォーマンスが問題であることを確認する必要があります。

IPCの速度が原因で問題が発生した場合は、パイプを使用するのではなく、共有メモリに切り替えることを検討する必要があります。

転送速度のテストを行う場合は、ほとんどすべての種類のトンネルを作成できる非常に用途の広いプログラムであるsocatを試してください。


47

共有メモリソリューションで得られる最良の結果。

名前付きパイプは、TCPソケットよりもわずか16%優れています

結果はIPCベンチマークで得られます

  • システム:Linux(Linux ubuntu 4.4.0 x86_64 i7-6700K 4.00GHz)
  • メッセージ:128バイト
  • メッセージ数:1000000

パイプベンチマーク:

Message size:       128
Message count:      1000000
Total duration:     27367.454 ms
Average duration:   27.319 us
Minimum duration:   5.888 us
Maximum duration:   15763.712 us
Standard deviation: 26.664 us
Message rate:       36539 msg/s

FIFO(名前付きパイプ)ベンチマーク:

Message size:       128
Message count:      1000000
Total duration:     38100.093 ms
Average duration:   38.025 us
Minimum duration:   6.656 us
Maximum duration:   27415.040 us
Standard deviation: 91.614 us
Message rate:       26246 msg/s

Message Queueベンチマーク:

Message size:       128
Message count:      1000000
Total duration:     14723.159 ms
Average duration:   14.675 us
Minimum duration:   3.840 us
Maximum duration:   17437.184 us
Standard deviation: 53.615 us
Message rate:       67920 msg/s

共有メモリのベンチマーク:

Message size:       128
Message count:      1000000
Total duration:     261.650 ms
Average duration:   0.238 us
Minimum duration:   0.000 us
Maximum duration:   10092.032 us
Standard deviation: 22.095 us
Message rate:       3821893 msg/s

TCPソケットのベンチマーク:

Message size:       128
Message count:      1000000
Total duration:     44477.257 ms
Average duration:   44.391 us
Minimum duration:   11.520 us
Maximum duration:   15863.296 us
Standard deviation: 44.905 us
Message rate:       22483 msg/s

Unixドメインソケットのベンチマーク:

Message size:       128
Message count:      1000000
Total duration:     24579.846 ms
Average duration:   24.531 us
Minimum duration:   2.560 us
Maximum duration:   15932.928 us
Standard deviation: 37.854 us
Message rate:       40683 msg/s

ZeroMQベンチマーク:

Message size:       128
Message count:      1000000
Total duration:     64872.327 ms
Average duration:   64.808 us
Minimum duration:   23.552 us
Maximum duration:   16443.392 us
Standard deviation: 133.483 us
Message rate:       15414 msg/s

1
詳細なベンチマークをありがとうございます。「multiprocessing.Queue」と「Message Queue」の意味ですか?
ovunccetin

1
メッセージキューシステムXSIメッセージキューである(man7.org/linux/man-pages/man0/sys_msg.h.0p.html
chronoxor

34

shodanexに同意します。まだ問題のないものを最適化しようとしているようです。ソケットがボトルネックになることがわかっているのでない限り、私はそれらを使用します。

名前付きパイプを使用して誓う多くの人々は少し節約できます(他のすべてがどのように書かれているかによって異なります)が、IPC応答のブロックに、有用な作業を行うよりも多くの時間を費やすコードになります。確かに、非ブロッキングスキームはこれを助けますが、それらは扱いにくい場合があります。何年もかけて古いコードを現代に持ち込んだことは、私が見たほとんどの場合、スピードアップはほとんどゼロであると言えるでしょう。

ソケットがあなたを遅くすると本当に思っているのなら、ロックの使い方に注意して共有メモリを使ってゲートから出てください。繰り返しになりますが、実際には、わずかな高速化が見つかるかもしれませんが、相互排他ロックを待機している間にその一部が無駄になっていることに注意してください。私は旅行擁護するつもりはないのfutex地獄(まあ、ない非常にあなたの経験に応じて、2015年にはもう地獄を)。

ポンドはポンドで、ソケットは(ほとんど)常にモノリシックカーネルの下でユーザー空間IPCを実現するための最良の方法であり、(通常)デバッグと保守が最も簡単です。


2
多分遠いユートピア、将来のある日は、私たちは、暗黙的には、すべての(プロセス間など)私たちは、現在達成するためにオーバー割れたガラスを歩く能力を提供することを完全に新しい、モジュラー、近代的なカーネルを持っているよ...ちょっと... 1は、夢を見ることができます
Gukki5

27

ソケットは必ずしもIP(およびTCPまたはUDP)を意味するわけではないことに注意してください。UNIXソケット(PF_UNIX)を使用することもできます。これにより、127.0.0.1への接続に比べてパフォーマンスが著しく向上します。


1
Windowsはどうですか?
Pacerier

1
@Pacerier残念なことに、UNIXの抽象名前空間と同じ方法でWindowsにローカルソケットを作成することはできません。私はPF_UNIXソケットが、このページで説明されている他のほとんどの方法よりもかなり高速(> 10%)であることを発見しました。
EntangledLoops 2017

1
devblogs.microsoft.com/commandline/af_unix-comes-to-windows update、UnixソケットがWindows 10で利用可能になりました。
eri0o


11

速度が必要ない場合は、ソケットが最も簡単な方法です。

あなたが見ているものが速度である場合、最も速い解決策は名前付きパイプではなく共有メモリです。


8

名前付きパイプとの双方向通信の場合:

  • プロセスが少ない場合は、2つのパイプを2方向(processA2ProcessBおよびprocessB2ProcessA)に開くことができます。
  • 多くのプロセスがある場合は、すべてのプロセス(processAin、processAout、processBin、processBout、processCin、processCoutなど)のパイプを開閉できます。
  • または、いつものようにハイブリッドにすることができます:)

名前付きパイプの実装は非常に簡単です。

たとえば、名前付きパイプを使用してプロジェクトをCに実装しました。これは、標準のファイル入出力ベースの通信(fopen、fprintf、fscanf ...)のおかげで、非常に簡単でクリーンです(それが考慮事項である場合)。

私はそれらをjavaでコーディングしました(オブジェクトをシリアル化して送信していました!)

名前付きパイプには1つの欠点があります。

  • それらはファイルシステムに依存しているため、ソケットのような複数のコンピューターではスケーリングしません(共有ファイルシステムはオプションではないと想定)

8

ソケットの問題の1つは、バッファをフラッシュする方法がないことです。すべてのデータを収集して40ミリ秒後にフラッシュするNagleアルゴリズムと呼ばれるものがあります。したがって、それが帯域幅ではなく応答性である場合は、パイプを使用する方がよいでしょう。

ソケットオプションTCP_NODELAYを使用してNagleを無効にすることはできますが、その場合、読み取り側は1回の読み取り呼び出しで2つの短いメッセージを受け取ることはありません。

だからテストしてみたところ、何もない状態になり、共有メモリにpthread mutexとセマフォを使ってメモリマップベースのキューを実装し、多くのカーネルシステムコールを回避しました(しかし、今日はそれほど遅くありません)。


3
「それをテストする」<-生きるための言葉。
Koshinae

6

名前付きパイプとソケットは機能的に同等ではありません。ソケットはより多くの機能を提供します(最初は双方向です)。

どちらが優れているかはわかりませんが、それは問題ではないと私は強く信じています。

Unixドメインソケットはtcpソケットとほぼ同じように機能しますが、ローカルマシン上でのみ(おそらく少し)オーバーヘッドが低くなります。

Unixソケットの速度が十分でなく、大量のデータを転送している場合は、クライアントとサーバーの間で共有メモリを使用することを検討してください(これは設定が非常に複雑です)。

UnixとNTにはどちらも「名前付きパイプ」がありますが、機能セットはまったく異なります。


1
2つのパイプを開くと、Bidiの動作も得られます。
パセリエ2017

4

ZeroMQ [ zmq / 0mq ]のような軽量ソリューションを使用できます。非常に使いやすく、ソケットよりも劇的に高速です。


2
Amitさん、Martin SUSTRIKの次のアートワークであるPOSIX準拠が好きかもしれませんnanomsg。とにかく、この素晴らしい場所を歓迎して楽しんで、積極的に貢献するメンバーになってください。
user3666197 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.