1.3.5. How to profile your Code¶
Depending on the Use Case of the code it is necessary or might be useful to profile ROS Nodes. For example is is rather unimportant whether an GUI for changing Parameters is as fast as possible or not. But since SLAM is executed upto 40-300 times per second it is essential to have very performant Code. Profiling the Code is, when done correctly, a very useful tool to find slow code parts so that they can be improved.
1.3.5.1. How to profile Python scripts¶
It is rather easy to debug complete python scripts.
You have to do three things in your script:
Import
yappi
and set cpu typeimport yappi yappi.set_clock_type('cpu')
Start yappi profiling
import yappi yappi.start()
End yappi profiling and save results
yappi.stop() path = '/workspace/as_ros/rosbags/profiling/callgrind.out_<name>' yappi.get_func_stats().save(path, type='callgrind')
If you want, you can add a functionality to automatically export the profiling to a svg image:
os.system(f'gprof2dot -w -s -f callgrind {path} | dot -Tsvg -o {path}.svg')
Adapt the path to your liking if you want to save the profiling under a more meaningful path
You are ready to profile you python script by simply executing it.
You can now either use the automatically created svg image to analyze the profiling or analyze it according to Analyze profiling with KCachegrind.
1.3.5.2. How to profile C/C++ programs¶
Todo
This needs to be tested and correctly documented. Here is one possible approach http://wiki.ros.org/roslaunch/Tutorials/Profiling%20roslaunch%20nodes
1.3.5.3. How to profile ROS Nodes¶
Another Use Case is to profile ROS Nodes rather than python scripts or c programs.
1.3.5.3.1. Preparing to profile ROS Nodes written in Python¶
Profiling ROS Nodes written in Python is even simpler than profiling Python scripts.
You just have to add an launch-prefix
in the launch file, e.g.:
<node name="slam" pkg="slam" type="slam.py" output="screen" required="$(eval arg('required') == 'yes')"
launch-prefix="/usr/local/bin/yappi -b -f callgrind -o /workspace/as_ros/rosbags/profiling/callgrind.out_$(anon slam)"/>
To be able to use the same launch file with and without profiling the ROS Node, you should add an profiling
argument which controls this behaviour.
This is a minimal working example:
<?xml version="1.0" encoding="utf-8"?>
<launch>
<arg name="profiling" default="no"/>
<group if="$(eval arg('profiling') == 'yes')">
<node name="slam" pkg="slam" type="slam.py" output="screen" required="$(eval arg('required') == 'yes')"
launch-prefix="/usr/local/bin/yappi -b -f callgrind -o /workspace/as_ros/rosbags/profiling/callgrind.out_$(anon slam)"/>
</group>
<group unless="$(eval arg('profiling') == 'yes')">
<node name="slam" pkg="slam" type="slam.py" output="screen" required="$(eval arg('required') == 'yes')"/>
</group>
</launch>
1.3.5.3.2. Preparing to profile ROS Nodes written in C/C++¶
Todo
This needs to be tested and correctly documented. Here is one possible approach http://wiki.ros.org/roslaunch/Tutorials/Profiling%20roslaunch%20nodes
1.3.5.3.3. Profiling ROS Nodes¶
At this moment every launch file for the pipeline ros modules (inference / perception, local mapping, slam, path_planning, motion planning and control) implemented the above explained profiling functionality.
Thus all those launch files can be started with profiling:=yes
. Also the general pipeline debug launch file (utilities/debug_pipeline
) implements the same interface.
The respective profiling files can be found under rosbags/profiling/callgrind.out_<module_name>_<random_id>
. You will need them to How to analyze profiling.
1.3.5.4. How to analyze profiling¶
There are different tools to visualize the results of profiling. Some of those will be shortly presendet in the following.
1.3.5.4.1. Analyze profiling with gprof2dot¶
You can use gprof2dot to create dot graphs from profiling files. They are more or less call graphs with timing statistics of the respective functions. An example is shown in Example of Callgraph with timing statistics created with gprof2dot.
You can convert an profiling file within the docker container with:
gprof2dot -w -s -f callgrind "path/to/callgrind.out" | dot -Tsvg -o "path/to/callgrind.out.svg"
Fig. 1.4 Example of Callgraph with timing statistics created with gprof2dot¶
1.3.5.4.2. Analyze profiling with KCachegrind¶
KCachegrind is an interactive GUI which offers a rich feature spektrum. You can start KCachegrind by executing in the docker container:
kcachegrind
Remember to follow Using GUIs inside an AS ROS container.
1.3.5.4.3. Analyze profiling with SnakeViz¶
In theory you can also use SnakeViz to visualize profiling. To use SnakeViz you need to use another profiling format when using yappi: pstats.