MyEnigma

とある自律移動システムエンジニアのブログです。#Robotics #Programing #C++ #Python #MATLAB #Vim #Mathematics #Book #Movie #Traveling #Mac #iPhone

ROS C++のコードをgprofでプロファイリングする方法


gprofとは?

gprofはGNUプロジェクトツール群の一つで、

ソフトウェアのパフォーマンス解析ツールです。


あるソフトウェアの中で、

どの部分がどれだけ計算時間がかかっているかなどを

解析できます。


このgprofは、C,C++,Pascal,fortranのコードで使うことができます。


下記はROSにおいてgrofを使ったプロファイリングの実施方法です。

(ROS専用の機能 or ツールはまったく使っていないので、

UNIXソフトのプロファイリングの方法と言った方がいいかもしれません)

1.gprofのインストール

Ubuntu12.04ではすでにインストールされていた。

インストールされていない場合は、

sudo apt-get install binutils

2. プロファイリング対象のノードのCMakeLists.txtを修正

gprofでプロファイル結果のファイルを生成するために、

プロファイリングをしたいノードのCMakeLists.txtに

下記のコードを追加します。

# For profiling with gprof
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pg")
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -pg")

3. プロファイリング対象のノードを正常終了するようにする。

基本的に、

gprofは、対象のソフトウェアが正常終了しないと、

プロファイルのログファイルを作ってくれません。

(ctrl+cではだめ)

しかし、ROSのソフトの場合、

while (ros::ok()){
	//処理	
}

で無限ループを回して、処理を実施させている場合、

ctrl-Cでもログファイルを作ってくれます。


しかし、gprofは0.01秒刻みでプロファイリングを行うため、

あまりにもノード起動時間が短いと、

分かりにくいプロファイル結果になってしまうので注意が必要です。

4. コンパイル(make)する

これでプロファイルのログを出力するようになります。

5. プロファイリング対象のノードを起動する。

対象のノードを起動してCtrl-Cで正常終了することを確認します。


すると,rosrunでノードを起動した場合ではカレントディレクトリに、

roslaunchで起動した場合は、~/.ros/に

gmon.outというプロファイル結果のファイルが生成されるはずです。

6. プロファイリングの結果をテキストとして出力する。

先程のgmon.outを使って、

gprof bin/node ./gmon.out > profile.log

とすることで、profile.logというファイルにプロファイルの結果が出力されます。


このプロファイルログの見方に関しては、下記の参考資料を参照下さい。

7. プロファイリングの結果を可視化する

先程のテキストファイルは、非常に見づらいので、

各関数のプロファイルの結果を可視化したくなります。


そこで、Gprof2Dotというツールを使います。

このソフトはgprofの結果を、

可視化して画像ファイルにするツールです。

下記のコマンドでソフトをダウンロードして、

git clone https://code.google.com/p/jrfonseca.gprof2dot/


下記のコマンドでgraph.pngという名前で可視化結果が出力されます。

gprof bin/node | ./jrfonseca.gprof2dot/gprof2dot.py | dot -Tpng -o graph.png


下記は出力される画像ファイルのサンプルです。

http://wiki.jrfonseca.googlecode.com/git/gprof2dot.png


計算時間で大きな割合を占めている関数(四角いブロック)は

赤や緑色で表示されるため、それらの関数を最適化すればいいことがわかります。


非常に便利ですね