- ベストアンサー
AF_UNIXのsocketと共有メモリを使ったリングバッファーの速度比較
いま、仕事でlinux上で2つのプロセスを動かし、プロセスの間で、高速で大量のデータの受け渡しが必要なプログラムを作っています。プロセス間の通信は普通の socket で AF_UNIX を使っています。 できるだけ速度を上げたいのですが、AF_UNIXのsocketのかわりに共有メモリを使ってリングバッファーでキューを作ってデータを送るという案が出ました。この方法によって速度の向上は期待できるでしょうか?
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
プロセスAからプロセスBへソケットを使用してデータを送信する場合、以下のようにメモリへのread/writeが発生すると思います。 1)プロセスA上のバッファへ送信データを書き込む 2)プロセスA上のバッファよりカーネル上のバッファへコピー 3)カーネル上のバッファよりプロセスB上のバッファへコピー 4)プロセスB上のバッファの受信データを読み込む 共用メモリを使用した場合は、2)および3)のread/write部分を省略できます。 2)および3)の部分は実際にはsend()/recv()を使用して行いますが、send()/recv()はデータのコピーだけではなく送信の制御のための作業を行います(当たり前ですが)。 send()/recv()の制御機構の処理時間と自前の排他制御の処理時間が同程度であれば、大量データのコピー処理を削減できるので速度の向上を期待できるのではないでしょうか。
その他の回答 (2)
- hidebun
- ベストアンサー率50% (92/181)
共有メモリを使って速度の向上は期待できると私も思います。 が、そもそも送り側と受け側のプロセスが同一マシン上で 同時に動作できるのか?ということは考慮されているのでしょうか。 送り側・受け側が同一マシン上で動くと、双方の動作によって、 CPUの奪い合いになり、動作速度が上がらない可能性があります。 仮に、その実装でOKだったとしても、受け側のプロセスが2つに なったら、破綻するようなシステムで良いのかなど、後々のことまで 考えて設計したほうが良いと思います。 2プロセスなら、DualCoreなら問題ないかもしれませんが。
- notnot
- ベストアンサー率47% (4900/10358)
大容量データということで、ソケットのバッファを十分大きく取っていたとして、ソケットの場合、送り側の送信バッファと受け側の受信バッファが必要ですが(プロセスの特性によっては同じサイズを確保する必要はないわけですが)、共有メモリを使った場合だと1つでいいので、同じメモリ使用量の場合だと2倍の大きさのバッファを取れることになります。また、排他制御も自分ですることになるので、プロセスの実行状態と待ち状態を自分で細かく制御できるわけですから、速くできると思います。 データ量とバッファサイズの比にもよるのかな。ソケットでも、データが全部入りきれるだけのバッファが取れるのであれば、共有メモリ化による速度向上は、プログラムが複雑になるデメリットを上回らないのではないかなあ。
お礼
ご回答ありがとうございます。 それなりの効果は期待できるのでね。 期待ができるのならやってみたいと思います。手間は、sendとrecvの代用品を作って、同じ名前で使えるようにしてやれば、ソケットの生成部分だけなので、たいしたことはないと思います。 しかし、最初から共有メモリを使うようにシステム全体を設計していればもっとシンプルにできたのですが、いまから変更だとsendとrecvをエミュレーションするような仕様にしなければならないので、その分は効率が悪いですね。
補足
脱字でした それなりの効果は期待できるのでね。 ↓ それなりの効果は期待できるのですね。
お礼
ご回答ありがとうございました。 今すでにテストを開始していて、速度が向上していることを確認しました。