質問: C++で非同期通信を実装しています。環境はLinux(今のところUbuntuとCentOSが前提)。 このクラスを使用する側は、任意のタイミングで好きなだけsend()を使える仕様で考えています。 ``` 例: myAsyncClass myAsync; myAsync.connect("host"); myAsync.send(buf1,len1); // ←非同期で処理されてすぐリターンする. myAsync.send(buf2,len2); // ←非同期で処理されてすぐリターンする. myAsync.send(buf3,len3); // ←非同期で処理されてすぐリターンする. // 受信はあらかじめ登録したコールバックか何かで行う. ``` 内部でソケットが書き込み可能になったらシステムコールのsend()を呼びます。 しかし、なるべくシステムコールの呼び出し回数は少ない方が良いため、書き込み可能になった時にbuf1とbuf2とbuf3を全て持っていたら、それらを連結して一回だけsend()を呼ぼうかと思っています。 ですが、buf1とbuf2とbuf3のメモリを連結するためには、buf1の末尾(あるいは自分で用意した別バッファ)へ動的確保を行い、buf2とbuf3をコピーするコストが発生します。 ここで迷っているのは、メモリの確保とコピーを行うくらいなら、素直にsend()を3回呼んだ方がコストが少ないのではないか?ということです。 このあたりの知見をお持ちの方がいらしたらアドバイスお願いします。 もちろんケースバイケースで、コピーする頻度や量にもよるという意見もあるかと思いますが。。
回答: ソケットの通信の効率化をネットワークカードレベルで考える の回答にある、 > > scatter/gather I/Oまたはvectored I/Oと呼ばれる機構 > > > これがまさにその、まとめて実行するものです。 Linuxのstruct iovec や、Winsockの WSABuf は 簡単に言えば (*buf, len) の構造体で、sendmsgやWSASendではその配列を含む引数を渡すことにより、複数の(*buf, len)を一度に処理します。 性能が変わるかどうかはアプリケーションによるので、実測比較してくださいとしか言えません。