From 08963df92644a5de963d80bd206b4185de77d822 Mon Sep 17 00:00:00 2001 From: Scott K Logan Date: Wed, 25 Nov 2020 14:51:59 -0800 Subject: [PATCH] Add benchmarks for components (#1476) Signed-off-by: Scott K Logan --- rclcpp_components/CMakeLists.txt | 12 ++ rclcpp_components/package.xml | 1 + .../test/benchmark/benchmark_components.cpp | 121 ++++++++++++++++++ 3 files changed, 134 insertions(+) create mode 100644 rclcpp_components/test/benchmark/benchmark_components.cpp diff --git a/rclcpp_components/CMakeLists.txt b/rclcpp_components/CMakeLists.txt index f438a2b0bc..bd8ffddee8 100644 --- a/rclcpp_components/CMakeLists.txt +++ b/rclcpp_components/CMakeLists.txt @@ -65,6 +65,10 @@ endif() if(BUILD_TESTING) find_package(ament_lint_auto REQUIRED) + find_package(ament_cmake_google_benchmark REQUIRED) + find_package(benchmark REQUIRED) + # Give cppcheck hints about macro definitions coming from outside this package + get_target_property(ament_cmake_cppcheck_ADDITIONAL_INCLUDE_DIRS benchmark::benchmark INTERFACE_INCLUDE_DIRECTORIES) ament_lint_auto_find_test_dependencies() set(components "") @@ -109,6 +113,14 @@ if(BUILD_TESTING) if(TARGET test_component_manager_api) target_link_libraries(test_component_manager_api component_manager) endif() + + ament_add_google_benchmark(benchmark_components + test/benchmark/benchmark_components.cpp + APPEND_ENV AMENT_PREFIX_PATH=${CMAKE_CURRENT_BINARY_DIR}/test_ament_index/$ + APPEND_LIBRARY_DIRS "${append_library_dirs}") + if(TARGET benchmark_components) + target_link_libraries(benchmark_components component_manager) + endif() endif() install( diff --git a/rclcpp_components/package.xml b/rclcpp_components/package.xml index 824ba4f6ab..11ad6e91cf 100644 --- a/rclcpp_components/package.xml +++ b/rclcpp_components/package.xml @@ -23,6 +23,7 @@ composition_interfaces rclcpp + ament_cmake_google_benchmark ament_cmake_gtest ament_lint_auto ament_lint_common diff --git a/rclcpp_components/test/benchmark/benchmark_components.cpp b/rclcpp_components/test/benchmark/benchmark_components.cpp new file mode 100644 index 0000000000..6fbe6df107 --- /dev/null +++ b/rclcpp_components/test/benchmark/benchmark_components.cpp @@ -0,0 +1,121 @@ +// Copyright 2020 Open Source Robotics Foundation, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "benchmark/benchmark.h" + +#include + +#include +#include +#include + +#include "rclcpp_components/component_manager.hpp" + +class ComponentTest : public benchmark::Fixture +{ +public: + ComponentTest() + : component_manager_name("my_manager") + { + } + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Woverloaded-virtual" +#endif + void SetUp(benchmark::State &) override + { + rcutils_logging_set_default_logger_level(RCUTILS_LOG_SEVERITY_WARN); + + context = std::make_shared(); + context->init(0, nullptr, rclcpp::InitOptions().auto_initialize_logging(false)); + + rclcpp::ExecutorOptions exec_options; + exec_options.context = context; + + executor = std::make_shared(exec_options); + + manager = std::make_shared( + executor, component_manager_name, rclcpp::NodeOptions().context(context)); + executor->add_node(manager); + } + + void TearDown(benchmark::State &) override + { + context->shutdown("Test is complete"); + + manager.reset(); + executor.reset(); + context.reset(); + } +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + + const std::string component_manager_name; + +protected: + rclcpp::Context::SharedPtr context; + rclcpp::executors::SingleThreadedExecutor::SharedPtr executor; + std::shared_ptr manager; +}; + +BENCHMARK_F(ComponentTest, get_component_resources)(benchmark::State & state) +{ + for (auto _ : state) { + std::vector resources = + manager->get_component_resources("rclcpp_components"); + if (resources.size() != 3) { + state.SkipWithError("Wrong number of components found"); + break; + } + } +} + +BENCHMARK_F(ComponentTest, create_component_factory)(benchmark::State & state) +{ + const std::vector resources = + manager->get_component_resources("rclcpp_components"); + if (resources.size() != 3) { + state.SkipWithError("Wrong number of components found"); + return; + } + + for (auto _ : state) { + manager->create_component_factory(resources[0]).reset(); + } +} + +BENCHMARK_F(ComponentTest, create_node_instance)(benchmark::State & state) +{ + const std::vector resources = + manager->get_component_resources("rclcpp_components"); + if (resources.size() != 3) { + state.SkipWithError("Wrong number of components found"); + return; + } + + // Choosing resource 0 - the other two test components were shown empirically to yield + // the same performance charactarisitics, so they shouldn't need their own benchmarks. + const std::shared_ptr factory = + manager->create_component_factory(resources[0]); + + const rclcpp::NodeOptions options = rclcpp::NodeOptions().context(context); + + for (auto _ : state) { + rclcpp_components::NodeInstanceWrapper node = factory->create_node_instance(options); + benchmark::DoNotOptimize(node); + benchmark::ClobberMemory(); + } +}