From 9d8348f0ce750a68770d0cf251701a4ab76fba8d Mon Sep 17 00:00:00 2001 From: pavelkumbrasev Date: Thu, 13 Jun 2024 10:40:29 +0100 Subject: [PATCH 1/3] Fix memory leak for static_partitioner Signed-off-by: pavelkumbrasev --- include/oneapi/tbb/partitioner.h | 7 +++++-- test/tbb/test_task.cpp | 26 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/include/oneapi/tbb/partitioner.h b/include/oneapi/tbb/partitioner.h index f09786c022..4e97d684fa 100644 --- a/include/oneapi/tbb/partitioner.h +++ b/include/oneapi/tbb/partitioner.h @@ -46,6 +46,7 @@ #include "cache_aligned_allocator.h" #include "task_group.h" // task_group_context #include "task_arena.h" +#include "global_control.h" #include #include @@ -70,7 +71,8 @@ class affinity_partitioner_base; inline std::size_t get_initial_auto_partitioner_divisor() { const std::size_t factor = 4; - return factor * static_cast(max_concurrency()); + return factor * std::min(static_cast(max_concurrency()), + tbb::global_control::active_value(tbb::global_control::max_allowed_parallelism)); } //! Defines entry point for affinity partitioner into oneTBB run-time library. @@ -90,7 +92,8 @@ class affinity_partitioner_base: no_copy { /** Retains values if resulting size is the same. */ void resize(unsigned factor) { // Check factor to avoid asking for number of workers while there might be no arena. - unsigned max_threads_in_arena = static_cast(max_concurrency()); + unsigned max_threads_in_arena = std::min(static_cast(max_concurrency()), + tbb::global_control::active_value(tbb::global_control::max_allowed_parallelism)); std::size_t new_size = factor ? factor * max_threads_in_arena : 0; if (new_size != my_size) { if (my_array) { diff --git a/test/tbb/test_task.cpp b/test/tbb/test_task.cpp index 876e351006..8dc154f47c 100644 --- a/test/tbb/test_task.cpp +++ b/test/tbb/test_task.cpp @@ -20,6 +20,7 @@ #include "common/spin_barrier.h" #include "common/utils_concurrency_limit.h" #include "common/cpu_usertime.h" +#include "common/memory_usage.h" #include "tbb/task.h" #include "tbb/task_group.h" @@ -840,3 +841,28 @@ TEST_CASE("Check correct arena destruction with enqueue") { tbb::finalize(handle, std::nothrow_t{}); } } + +//! \brief \ref regression +TEST_CASE("Check that memory does not leak with static_partitioner + global_control") { + tbb::global_control gbl_ctrl{ tbb::global_control::max_allowed_parallelism, std::size_t(tbb::this_task_arena::max_concurrency() / 2) }; + + size_t current_memory_usage = 0, previous_memory_usage = 0, stability_counter = 0; + bool no_memory_leak = false; + std::size_t num_iterations = 100; + for (std::size_t i = 0; i < num_iterations; ++i) { + for (std::size_t j = 0; j < 100; ++j) { + tbb::parallel_for(0, 1000, [] (int) {}, tbb::static_partitioner{}); + } + + current_memory_usage = utils::GetMemoryUsage(); + stability_counter = current_memory_usage==previous_memory_usage ? stability_counter + 1 : 0; + // If the amount of used memory has not changed during 5% of executions, + // then we can assume that the check was successful + if (stability_counter > num_iterations / 20) { + no_memory_leak = true; + break; + } + previous_memory_usage = current_memory_usage; + } + REQUIRE_MESSAGE(no_memory_leak, "Seems we get memory leak here."); +} From 975f9bf2246cc766fe6c7c7360b71fc7854f43ca Mon Sep 17 00:00:00 2001 From: pavelkumbrasev Date: Thu, 13 Jun 2024 10:46:45 +0100 Subject: [PATCH 2/3] Update copyright Signed-off-by: pavelkumbrasev --- include/oneapi/tbb/partitioner.h | 2 +- test/tbb/test_task.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/oneapi/tbb/partitioner.h b/include/oneapi/tbb/partitioner.h index 4e97d684fa..b411f75a84 100644 --- a/include/oneapi/tbb/partitioner.h +++ b/include/oneapi/tbb/partitioner.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2005-2023 Intel Corporation + Copyright (c) 2005-2024 Intel Corporation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/test/tbb/test_task.cpp b/test/tbb/test_task.cpp index 8dc154f47c..e30b22888c 100644 --- a/test/tbb/test_task.cpp +++ b/test/tbb/test_task.cpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2005-2023 Intel Corporation + Copyright (c) 2005-2024 Intel Corporation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. From 8ba0d1340daaac730cd1f2225efb2a75d01be8d5 Mon Sep 17 00:00:00 2001 From: Pavel Kumbrasev Date: Thu, 13 Jun 2024 12:21:02 +0100 Subject: [PATCH 3/3] Align expression types --- include/oneapi/tbb/partitioner.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/oneapi/tbb/partitioner.h b/include/oneapi/tbb/partitioner.h index b411f75a84..9961ace5a3 100644 --- a/include/oneapi/tbb/partitioner.h +++ b/include/oneapi/tbb/partitioner.h @@ -92,8 +92,8 @@ class affinity_partitioner_base: no_copy { /** Retains values if resulting size is the same. */ void resize(unsigned factor) { // Check factor to avoid asking for number of workers while there might be no arena. - unsigned max_threads_in_arena = std::min(static_cast(max_concurrency()), - tbb::global_control::active_value(tbb::global_control::max_allowed_parallelism)); + unsigned max_threads_in_arena = unsigned(std::min(static_cast(max_concurrency()), + tbb::global_control::active_value(tbb::global_control::max_allowed_parallelism))); std::size_t new_size = factor ? factor * max_threads_in_arena : 0; if (new_size != my_size) { if (my_array) {