0
$\begingroup$

I am working on optimizing subscriber-side delays in ROS 2. When handling large data samples, I noticed that most delays occur during the std::vector::resize() operation in the FastCDR library while subscribing to data of type std_msgs::msg::ByteMultiArray. After inspecting the data structure in the ROS 2 build folder, I believe initializing the vector with a fixed size could help reduce delays caused by runtime memory allocation. I want to experiment with the std::vector::reserve() operation for this specific type.

The below code represents the ByteMultiArray_ in byte_multi_array__struct.hpp file

// message struct
template<class ContainerAllocator>
struct ByteMultiArray_
{
  using Type = ByteMultiArray_<ContainerAllocator>;

  explicit ByteMultiArray_(rosidl_runtime_cpp::MessageInitialization _init = rosidl_runtime_cpp::MessageInitialization::ALL)
  : layout(_init)
  {
    (void)_init;
  }

  explicit ByteMultiArray_(const ContainerAllocator & _alloc, rosidl_runtime_cpp::MessageInitialization _init = rosidl_runtime_cpp::MessageInitialization::ALL)
  : layout(_alloc, _init)
  {
    (void)_init;
  }

  // field types and members
  using _layout_type =
    std_msgs::msg::MultiArrayLayout_<ContainerAllocator>;
  _layout_type layout;
  using _data_type =
    std::vector<unsigned char, typename std::allocator_traits<ContainerAllocator>::template rebind_alloc<unsigned char>>;
  _data_type data;
   
  // setters for named parameter idiom
  Type & set__layout(
    const std_msgs::msg::MultiArrayLayout_<ContainerAllocator> & _arg)
  {
    this->layout = _arg;
    return *this;
  }

The msg__struct.hpp.em file in rosidl_generator_cpp which used to create the file byte_multi_array__struct.hpp

  explicit @(message.structure.namespaced_type.name)_(const ContainerAllocator & _alloc, rosidl_runtime_cpp::MessageInitialization _init = rosidl_runtime_cpp::MessageInitialization::ALL)
@[if alloc_list]@
  : @(',\n    '.join(alloc_list))
@[end if]@
  {
@[if not member_list]@
    (void)_init;
@[end if]@
@[if not alloc_list]@
    (void)_alloc;
@[end if]@
@[if default_value_members]@
    if (rosidl_runtime_cpp::MessageInitialization::ALL == _init ||
      rosidl_runtime_cpp::MessageInitialization::DEFAULTS_ONLY == _init)
    {
@[  for membset in default_value_members]@
@[    for line in generate_default_string(membset)]@
      @(line)
@[    end for]@
@[  end for]@
@[  if zero_value_members]@
    } else if (rosidl_runtime_cpp::MessageInitialization::ZERO == _init) {
@[    for membset in zero_value_members]@
@[      for line in generate_zero_string(membset, '_alloc, _init')]@
      @(line)
@[      end for]@
@[    end for]@
@[  end if]@
    }
@[end if]@
@[if non_defaulted_zero_initialized_members]@
    if (rosidl_runtime_cpp::MessageInitialization::ALL == _init ||
      rosidl_runtime_cpp::MessageInitialization::ZERO == _init)
    {
@[  for membset in non_defaulted_zero_initialized_members]@
@[    for line in generate_zero_string(membset, '_alloc, _init')]@
      @(line)
@[    end for]@
@[  end for]@
    }
@[end if]@
  }

  // field types and members
@[for member in message.structure.members]@
  using _@(member.name)_type =
    @(msg_type_to_cpp(member.type));
  _@(member.name)_type @(member.name);
@[end for]@c

How can I include this modification? Do I need to update the.em file, and if so, how should I proceed?

Is there other efficient methods for this optimization in FastCDR?

$\endgroup$

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.