Skip to content

Creating/destroying a node results in inconsistent heap allocations #1417

@brawner

Description

@brawner

While adding performance tests (see #1411) for creating a basic rclcpp::Node, we noticed that the number of heap allocations during each iteration can vary during each call to rclcpp::Node's constructor. Even calling init/shutdown each time didn't help the variation.

With further investigation this may lead to some potential performance improvements.

Example of benchmark:

BENCHMARK_F(NodePerformanceTest, create_node_with_init)(benchmark::State & state)
{
  reset_heap_counters();
  for (auto _ : state) {
    state.PauseTiming();
    rclcpp::init(0, nullptr);
    state.ResumeTiming();
    
    reset_heap_counters();
    auto node = std::make_unique<rclcpp::Node>("node");
    printf("Construct heap allocations %lu\n", get_allocation_count());
    
    benchmark::DoNotOptimize(node);
    benchmark::ClobberMemory();
    
    state.PauseTiming();
    node.reset();
    rclcpp::shutdown();
    state.ResumeTiming();
  }
}

Result with rmw_fastrtps_cpp

Construct heap allocations 4909
Construct heap allocations 3673
Construct heap allocations 3674
Construct heap allocations 3672
Construct heap allocations 3670
Construct heap allocations 3670
Construct heap allocations 3670
Construct heap allocations 3650
Construct heap allocations 3673
Construct heap allocations 3681
Construct heap allocations 3660

With a similar benchmark measuring the destructor:

Destruct heap allocations 76
Destruct heap allocations 77
Destruct heap allocations 77
Destruct heap allocations 76
Destruct heap allocations 76
Destruct heap allocations 76
Destruct heap allocations 78
Destruct heap allocations 76
Destruct heap allocations 76
Destruct heap allocations 75
Destruct heap allocations 75
Destruct heap allocations 78
Destruct heap allocations 75

And rmw_cyclonedds_cpp

Construct heap allocations 5752
Construct heap allocations 4935
Construct heap allocations 4961
Construct heap allocations 4958
Construct heap allocations 4903
Construct heap allocations 4950
Construct heap allocations 4961
Construct heap allocations 4939
Construct heap allocations 4976
Construct heap allocations 4924
Destruct heap allocations 196
Destruct heap allocations 196
Destruct heap allocations 194
Destruct heap allocations 188
Destruct heap allocations 192
Destruct heap allocations 197
Destruct heap allocations 194
Destruct heap allocations 192
Destruct heap allocations 193
Destruct heap allocations 195
Destruct heap allocations 193
Destruct heap allocations 191
Destruct heap allocations 196
Destruct heap allocations 193

Also note worthy is that the first iteration had a significant increase in allocations, which is likely the real use case of an rclcpp user. But the caching effects will make it difficult for benchmarks to measure those initial allocations.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions