I’ve been using ROS2 for a year. Maybe previously you guys talked about this. However I’ve done experimental tests about the optimization C++ code ROS2 node and wrote a simple node.
#include "rclcpp/rclcpp.hpp"
class HelloWorldNode : public rclcpp::Node
{
public:
HelloWorldNode() : Node("hello_world_node")
{
RCLCPP_INFO(this->get_logger(), "Hello, World! This is a ROS2 node.");
}
};
int main(int argc, char **argv)
{
rclcpp::init(argc, argv);
rclcpp::spin(std::make_shared<HelloWorldNode>());
rclcpp::shutdown();
return 0;
}
Then by simply building the above code by using
colcon build
I got hello_node then explored assemble code
objdump -d <path>/hello_node > hello_node.asm
got around 5000 lines of instruction code in hello_node.asm, it seems like it didn’t do any optimization to the code. Then run the following command
then looked number instructions lines the number dramatically decreased from 5000 to 1700. the number of instruction lines in assemble doesn’t always mean it’s optimized yet it’s good factor.
“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”"
simple by adding “set(CMAKE_BUILD_TYPE Release)” to your CMakeLists.txt is enough. then you can simply use colcon build. Optimizations flags
This can be very dangerous with ROS. As soon as your package uses (or exports) any Eigen, PCL or OpenCV interfaces, it leads to hard-to-debug memory segfaults, because native optimizations can change memory layout of some optimized data structures. You always have to either compile whole your system with this flag (meaning, at least whole ROS, PCL library and OpenCV), or you have to live without it.
The only safe place where you can use it is if you are absolutely sure your node doesn’t use any of Eigen/PCL/OpenCV directly. Then you can compile it to gain speed without risking memory issues.
Things get even more complicated if you want to release your package on the buildfarm. Because then march=native actually optimizes for the buildfarm machine HW, which is not what you want. I have a released node that uses this here: ros-utils/cras_cpp_common/CMakeLists.txt at master · ctu-vras/ros-utils · GitHub . Basically, it just detects x86 vs arm64 and adds some basic SIMD flags, not all march=native.
If you do not want to go through the “hassle” of installing the mixins and using a command line option for every colcon build call, and, more importantly, want to use different settings for different packages, you can create a .meta file.
colcon build will use the default file colcon.meta, if it exists in the workspace. Otherwise, you can point to another file with the --metas option.
Example: Create the file colcon.meta in your workspace and set package-specific build arguments:
Now, when you run colcon build in the workspace, it will build package my_library_package_name in release mode and my_ros_node_package_name and debug mode. This is very useful if you are developing and only need to debug a part of your packages.
And to provide one more option, colcon more recently supports workspace-specific defaults files, so you can turn on a release build for individual workspaces vs packages if preferred.