nodelet時のメッセージ送受信の速度について

1,390 views
Skip to first unread message

Kenta Yonekura

unread,
Oct 31, 2016, 3:44:07 AM10/31/16
to ros-jap...@googlegroups.com
皆様

いつもお世話になっております。米倉です。

ノードをC++以外で書くなんてありえない!nodeletして、shared_ptrして、
メッセージをゼロコピーしないと、ROSで実効速度なんか出やしない!!と
webのどこかで見かけたので、ぬるま湯Pythonに頼りきりだった自分も
しぶしぶnodeletを勉強し始めました。

しかしふと、そう言っても、メッセージ送受信ってどれくらい早くなるのか
気になったので、速度を計測するパッケージを作ってみました。
https://github.com/yoneken/measure_message_passing

上記のパッケージで、
1. 1つのノード内
2. 1つのノード内 shared_ptr渡し
3. 2つのノード間
4. 2つのノード間 shared_ptr渡し
5. 2つのnodelet間
6. 2つのnodelet間 shared_ptr渡し
の6条件で速度を比較してみました。

期待した速度の結果としては、 1,3,4,5 << 2,6 といったものだったのですが、
実際は、 3,4 < 5,6 < 1,2 となってしまい、shared_ptrの効果が全く出ませんでした。
また、速度差としてもそこまで大きなものではありませんでした。
詳細な速度検証結果を以下のURLに記載しています。
https://github.com/yoneken/measure_message_passing/blob/master/README.md

この結果の理由として、
・そもそも私のnodeletの実装及びshared_ptrの使い方が間違っている
・最近、nodeletの実装が変わった
などの理由が考えられるのですが、いかがでしょうか?
詳しい方にアドバイスいただければ幸いです。

よろしくお願い致します。

/**
*@author Kenta Yonekura
*@mail mill...@gmail.com
*@see http://blog.livedoor.jp/k_yon/
*/

Takashi Ogura

unread,
Oct 31, 2016, 9:21:47 AM10/31/16
to ros-jap...@googlegroups.com

全然詳しくないですが、普通ノードレットはサイズの大きいメッセージに対してやるものです。

サンプルはサイズが小さいですよね。

画像とか、メッセージサイズを大幅に変えてやってみたらどうなりますかね〜。(今の100倍、1000倍、100000倍とか)


2016/10/31 16:44 "Kenta Yonekura" <mill...@gmail.com>:
--
このメールは Google グループのグループ「ROS JAPAN Users Group」の登録者に送られています。
このグループから退会し、グループからのメールの配信を停止するには ros-japan-users+unsubscribe@googlegroups.com にメールを送信してください。
その他のオプションについては、https://groups.google.com/d/optout にアクセスしてください。

Yukihiro Saito

unread,
Nov 1, 2016, 2:05:57 AM11/1/16
to ROS JAPAN Users Group
米倉さん

はじめまして。斉藤です。
(間違った情報を載せていたらすいません)
トピック通信において、ローカルホスト内のsocket通信によるデータコピーが占める割合は状況によると思いますが、5~20%程度だったと記憶しています。
その他はシリアライズ・デシリアライズの処理であり、これらが大部分を占めています。
今回の例では、メッセージのサイズが小さすぎたためシリアライズ・デシリアライズの処理がほぼほぼ0であり、良い結果がでていないものと思われます。
小倉さんと同じ回答になりますが、512KB~数MBの通信が発生する画像や点群で試すのが良いと思います。

トピック通信はshared_ptrで同一プロセス(≒ノード)で通信をした場合、intra通信扱いになりメッセージのシリアライズ・デシリアライズがなくなる+ゼロコピーとなります。
※nodeletは複数のノードの処理を1プロセス内で処理する。
そのため、期待される速度の結果としては、3=4<1=6となると思っています(2,3に関しては内部でshared_ptr渡しているかもしれないので私は分かりません)。

よろしくお願い致します。

2016年10月31日月曜日 22時21分47秒 UTC+9 Takashi Ogura:
このグループから退会し、グループからのメールの配信を停止するには ros-japan-use...@googlegroups.com にメールを送信してください。
その他のオプションについては、https://groups.google.com/d/optout にアクセスしてください。

Kenta Yonekura

unread,
Nov 1, 2016, 3:05:20 AM11/1/16
to ros-jap...@googlegroups.com
小倉さん、斉藤さん

米倉です。コメントありがとうございます。

お二方のアドバイスを元に、メッセージのサイズを約2MBの画像にしてみました。
https://github.com/yoneken/measure_message_passing

こちらで再実験したところ、速度は 4,3<<2,1,5,6 という順番になりました。
この結果から、ノード内(nodelet含む)であれば速度は上がるが、shared_ptrの
結果はよくわからないということが言えるかと思います。

ところが、実験をしている間に、
https://github.com/yoneken/measure_message_passing/blob/master/src/MeasureTime.cpp#L32
の部分にcoutを入れたところ、shared_ptrにしてもしなくても、出力を吐いたので、
明示的にshared_ptrにしなくても、勝手にshared_ptrでやりとりをされているのかもしれません。

/**
*@author Kenta Yonekura
*@mail mill...@gmail.com
*@see http://blog.livedoor.jp/k_yon/
*/


> このメールは Google グループのグループ「ROS JAPAN Users Group」に登録しているユーザーに送られています。

Kenta Yonekura

unread,
Dec 9, 2016, 2:44:44 PM12/9/16
to ros-jap...@googlegroups.com, Yonekura Kenta
皆さま

いつもお世話になっております.米倉です.

以前に報告させていただいたこちらの事象につきまして,自分の実装ミスが見つかり
想定されるとおりの結果が出るようになりましたので報告します.

以前,

ところが、実験をしている間に、
https://github.com/yoneken/measure_message_passing/blob/master/src/MeasureTime.cpp#L32
の部分にcoutを入れたところ、shared_ptrにしてもしなくても、出力を吐いたので、
明示的にshared_ptrにしなくても、勝手にshared_ptrでやりとりをされているのかもしれません。

と書いていたのですが,この挙動がやはり気になり,shared_ptrで受け取る関数を削除して
ビルドし実験してみたら,やはりNodelet+shared_ptrが一番速いという結果となりました.

それまで実験のため,subscribeする関数について,普通の型とshared_ptrにした型の
2つを同じ名前でオーバーロードで実装していたのですが,
こうすると普通の型で渡そうとしても,なぜか勝手にshared_ptrで渡されてしまい,
思ったとおりの結果が出ないようです.
ROSの機能なのかC++の機能なのかコンパイラの機能なのか,shared_ptrによる
ゼロコピーが可能な場合は,できるだけ自動でゼロコピーになるようになっているようです.

メッセージ送受信の速度については,QiitaのROSアドベントカレンダーのほうに結果をまとめた
記事を書きましたので,そちらもよろしければご参照ください.


/**
 *@author Kenta Yonekura (yoneken)
 *@mail mill...@gmail.com

2016/11/01 16:05、Kenta Yonekura <mill...@gmail.com> のメール:
Reply all
Reply to author
Forward
0 new messages