From a9fcf497758e4e06d58b2356821f38d828ff4173 Mon Sep 17 00:00:00 2001 From: Ilya Isaev Date: Fri, 24 Jan 2025 18:35:51 +0100 Subject: [PATCH] Add reference implementation for parallel_phase feature (#1570) Implement parallel_phase API proposed in RFC, add new entry points to the library, move the RFC to the experimental stage. Signed-off-by: pavelkumbrasev Signed-off-by: Isaev, Ilya Co-authored-by: pavelkumbrasev Co-authored-by: Aleksei Fedotov Co-authored-by: Alexey Kukanov --- include/oneapi/tbb/detail/_config.h | 6 +- include/oneapi/tbb/task_arena.h | 173 +++++++-- .../parallel_phase_for_task_arena}/README.md | 34 +- .../alternative_proposal.png | Bin .../completely_disable_new_behavior.png | Bin .../parallel_phase_introduction.png | Bin .../parallel_phase_sequence_diagram.png | Bin 0 -> 124339 bytes .../parallel_phase_state_final.png | Bin .../parallel_phase_state_initial.png | Bin src/tbb/arena.cpp | 71 +++- src/tbb/arena.h | 98 ++++- src/tbb/def/lin32-tbb.def | 4 +- src/tbb/def/lin64-tbb.def | 4 +- src/tbb/def/mac64-tbb.def | 4 +- src/tbb/def/win32-tbb.def | 4 +- src/tbb/def/win64-tbb.def | 4 +- src/tbb/waiters.h | 21 +- test/CMakeLists.txt | 1 + test/common/config.h | 5 +- test/tbb/test_parallel_phase.cpp | 343 ++++++++++++++++++ 20 files changed, 727 insertions(+), 45 deletions(-) rename rfcs/{proposed/parallel_block_for_task_arena => experimental/parallel_phase_for_task_arena}/README.md (87%) rename rfcs/{proposed/parallel_block_for_task_arena => experimental/parallel_phase_for_task_arena}/alternative_proposal.png (100%) rename rfcs/{proposed/parallel_block_for_task_arena => experimental/parallel_phase_for_task_arena}/completely_disable_new_behavior.png (100%) rename rfcs/{proposed/parallel_block_for_task_arena => experimental/parallel_phase_for_task_arena}/parallel_phase_introduction.png (100%) create mode 100644 rfcs/experimental/parallel_phase_for_task_arena/parallel_phase_sequence_diagram.png rename rfcs/{proposed/parallel_block_for_task_arena => experimental/parallel_phase_for_task_arena}/parallel_phase_state_final.png (100%) rename rfcs/{proposed/parallel_block_for_task_arena => experimental/parallel_phase_for_task_arena}/parallel_phase_state_initial.png (100%) create mode 100644 test/tbb/test_parallel_phase.cpp diff --git a/include/oneapi/tbb/detail/_config.h b/include/oneapi/tbb/detail/_config.h index e676b1558b..87a33e20ff 100644 --- a/include/oneapi/tbb/detail/_config.h +++ b/include/oneapi/tbb/detail/_config.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2005-2024 Intel Corporation + Copyright (c) 2005-2025 Intel Corporation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -534,4 +534,8 @@ #define __TBB_PREVIEW_TASK_GROUP_EXTENSIONS 1 #endif +#if TBB_PREVIEW_PARALLEL_PHASE || __TBB_BUILD +#define __TBB_PREVIEW_PARALLEL_PHASE 1 +#endif + #endif // __TBB_detail__config_H diff --git a/include/oneapi/tbb/task_arena.h b/include/oneapi/tbb/task_arena.h index 5ce41d99c9..e594b57171 100644 --- a/include/oneapi/tbb/task_arena.h +++ b/include/oneapi/tbb/task_arena.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2005-2023 Intel Corporation + Copyright (c) 2005-2025 Intel Corporation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -95,6 +95,11 @@ TBB_EXPORT void __TBB_EXPORTED_FUNC isolate_within_arena(d1::delegate_base& d, s TBB_EXPORT void __TBB_EXPORTED_FUNC enqueue(d1::task&, d1::task_arena_base*); TBB_EXPORT void __TBB_EXPORTED_FUNC enqueue(d1::task&, d1::task_group_context&, d1::task_arena_base*); TBB_EXPORT void __TBB_EXPORTED_FUNC submit(d1::task&, d1::task_group_context&, arena*, std::uintptr_t); + +#if __TBB_PREVIEW_PARALLEL_PHASE +TBB_EXPORT void __TBB_EXPORTED_FUNC enter_parallel_phase(d1::task_arena_base*, std::uintptr_t); +TBB_EXPORT void __TBB_EXPORTED_FUNC exit_parallel_phase(d1::task_arena_base*, std::uintptr_t); +#endif } // namespace r1 namespace d2 { @@ -122,6 +127,14 @@ class task_arena_base { normal = 2 * priority_stride, high = 3 * priority_stride }; + +#if __TBB_PREVIEW_PARALLEL_PHASE + enum class leave_policy : int { + automatic = 0, + fast = 1 + }; +#endif + #if __TBB_ARENA_BINDING using constraints = tbb::detail::d1::constraints; #endif /*__TBB_ARENA_BINDING*/ @@ -162,13 +175,36 @@ class task_arena_base { return (my_version_and_traits & core_type_support_flag) == core_type_support_flag ? my_max_threads_per_core : automatic; } +#if __TBB_PREVIEW_PARALLEL_PHASE + leave_policy get_leave_policy() const { + return (my_version_and_traits & fast_leave_policy_flag) ? leave_policy::fast : leave_policy::automatic; + } + + int leave_policy_trait(leave_policy lp) const { + return lp == leave_policy::fast ? fast_leave_policy_flag : 0; + } + + void set_leave_policy(leave_policy lp) { + my_version_and_traits |= leave_policy_trait(lp); + } +#endif + enum { - default_flags = 0 - , core_type_support_flag = 1 + default_flags = 0, + core_type_support_flag = 1, + fast_leave_policy_flag = 1 << 1 }; - task_arena_base(int max_concurrency, unsigned reserved_for_masters, priority a_priority) - : my_version_and_traits(default_flags | core_type_support_flag) + task_arena_base(int max_concurrency, unsigned reserved_for_masters, priority a_priority +#if __TBB_PREVIEW_PARALLEL_PHASE + , leave_policy lp +#endif + ) + : my_version_and_traits(default_flags | core_type_support_flag +#if __TBB_PREVIEW_PARALLEL_PHASE + | leave_policy_trait(lp) +#endif + ) , my_initialization_state(do_once_state::uninitialized) , my_arena(nullptr) , my_max_concurrency(max_concurrency) @@ -180,8 +216,16 @@ class task_arena_base { {} #if __TBB_ARENA_BINDING - task_arena_base(const constraints& constraints_, unsigned reserved_for_masters, priority a_priority) - : my_version_and_traits(default_flags | core_type_support_flag) + task_arena_base(const constraints& constraints_, unsigned reserved_for_masters, priority a_priority +#if __TBB_PREVIEW_PARALLEL_PHASE + , leave_policy lp +#endif + ) + : my_version_and_traits(default_flags | core_type_support_flag +#if __TBB_PREVIEW_PARALLEL_PHASE + | leave_policy_trait(lp) +#endif + ) , my_initialization_state(do_once_state::uninitialized) , my_arena(nullptr) , my_max_concurrency(constraints_.max_concurrency) @@ -259,31 +303,58 @@ class task_arena : public task_arena_base { * Value of 1 is default and reflects behavior of implicit arenas. **/ task_arena(int max_concurrency_ = automatic, unsigned reserved_for_masters = 1, - priority a_priority = priority::normal) - : task_arena_base(max_concurrency_, reserved_for_masters, a_priority) + priority a_priority = priority::normal +#if __TBB_PREVIEW_PARALLEL_PHASE + , leave_policy lp = leave_policy::automatic +#endif + ) + : task_arena_base(max_concurrency_, reserved_for_masters, a_priority +#if __TBB_PREVIEW_PARALLEL_PHASE + , lp +#endif + ) {} #if __TBB_ARENA_BINDING //! Creates task arena pinned to certain NUMA node task_arena(const constraints& constraints_, unsigned reserved_for_masters = 1, - priority a_priority = priority::normal) - : task_arena_base(constraints_, reserved_for_masters, a_priority) + priority a_priority = priority::normal +#if __TBB_PREVIEW_PARALLEL_PHASE + , leave_policy lp = leave_policy::automatic +#endif + ) + : task_arena_base(constraints_, reserved_for_masters, a_priority +#if __TBB_PREVIEW_PARALLEL_PHASE + , lp +#endif + ) {} //! Copies settings from another task_arena - task_arena(const task_arena &s) // copy settings but not the reference or instance + task_arena(const task_arena &a) // copy settings but not the reference or instance : task_arena_base( constraints{} - .set_numa_id(s.my_numa_id) - .set_max_concurrency(s.my_max_concurrency) - .set_core_type(s.my_core_type) - .set_max_threads_per_core(s.my_max_threads_per_core) - , s.my_num_reserved_slots, s.my_priority) + .set_numa_id(a.my_numa_id) + .set_max_concurrency(a.my_max_concurrency) + .set_core_type(a.my_core_type) + .set_max_threads_per_core(a.my_max_threads_per_core) + , a.my_num_reserved_slots, a.my_priority +#if __TBB_PREVIEW_PARALLEL_PHASE + , a.get_leave_policy() +#endif + ) + {} #else //! Copies settings from another task_arena task_arena(const task_arena& a) // copy settings but not the reference or instance - : task_arena_base(a.my_max_concurrency, a.my_num_reserved_slots, a.my_priority) + : task_arena_base(a.my_max_concurrency, + a.my_num_reserved_slots, + a.my_priority, +#if __TBB_PREVIEW_PARALLEL_PHASE + a.get_leave_policy() +#endif + ) {} #endif /*__TBB_ARENA_BINDING*/ @@ -292,7 +363,11 @@ class task_arena : public task_arena_base { //! Creates an instance of task_arena attached to the current arena of the thread explicit task_arena( attach ) - : task_arena_base(automatic, 1, priority::normal) // use default settings if attach fails + : task_arena_base(automatic, 1, priority::normal +#if __TBB_PREVIEW_PARALLEL_PHASE + , leave_policy::automatic +#endif + ) // use default settings if attach fails { if (r1::attach(*this)) { mark_initialized(); @@ -311,13 +386,20 @@ class task_arena : public task_arena_base { //! Overrides concurrency level and forces initialization of internal representation void initialize(int max_concurrency_, unsigned reserved_for_masters = 1, - priority a_priority = priority::normal) + priority a_priority = priority::normal +#if __TBB_PREVIEW_PARALLEL_PHASE + , leave_policy lp = leave_policy::automatic +#endif + ) { __TBB_ASSERT(!my_arena.load(std::memory_order_relaxed), "Impossible to modify settings of an already initialized task_arena"); if( !is_active() ) { my_max_concurrency = max_concurrency_; my_num_reserved_slots = reserved_for_masters; my_priority = a_priority; +#if __TBB_PREVIEW_PARALLEL_PHASE + set_leave_policy(lp); +#endif r1::initialize(*this); mark_initialized(); } @@ -325,7 +407,11 @@ class task_arena : public task_arena_base { #if __TBB_ARENA_BINDING void initialize(constraints constraints_, unsigned reserved_for_masters = 1, - priority a_priority = priority::normal) + priority a_priority = priority::normal +#if __TBB_PREVIEW_PARALLEL_PHASE + , leave_policy lp = leave_policy::automatic +#endif + ) { __TBB_ASSERT(!my_arena.load(std::memory_order_relaxed), "Impossible to modify settings of an already initialized task_arena"); if( !is_active() ) { @@ -335,6 +421,9 @@ class task_arena : public task_arena_base { my_max_threads_per_core = constraints_.max_threads_per_core; my_num_reserved_slots = reserved_for_masters; my_priority = a_priority; +#if __TBB_PREVIEW_PARALLEL_PHASE + set_leave_policy(lp); +#endif r1::initialize(*this); mark_initialized(); } @@ -404,6 +493,32 @@ class task_arena : public task_arena_base { return execute_impl(f); } +#if __TBB_PREVIEW_PARALLEL_PHASE + void start_parallel_phase() { + initialize(); + r1::enter_parallel_phase(this, /*reserved*/0); + } + void end_parallel_phase(bool with_fast_leave = false) { + __TBB_ASSERT(my_initialization_state.load(std::memory_order_relaxed) == do_once_state::initialized, nullptr); + // It is guaranteed by the standard that conversion of boolean to integral type will result in either 0 or 1 + r1::exit_parallel_phase(this, static_cast(with_fast_leave)); + } + + class scoped_parallel_phase { + task_arena& arena; + bool one_time_fast_leave; + public: + scoped_parallel_phase(task_arena& ta, bool with_fast_leave = false) + : arena(ta), one_time_fast_leave(with_fast_leave) + { + arena.start_parallel_phase(); + } + ~scoped_parallel_phase() { + arena.end_parallel_phase(one_time_fast_leave); + } + }; +#endif + #if __TBB_EXTRA_DEBUG //! Returns my_num_reserved_slots int debug_reserved_slots() const { @@ -472,6 +587,17 @@ inline void enqueue(F&& f) { enqueue_impl(std::forward(f), nullptr); } +#if __TBB_PREVIEW_PARALLEL_PHASE +inline void start_parallel_phase() { + r1::enter_parallel_phase(nullptr, /*reserved*/0); +} + +inline void end_parallel_phase(bool with_fast_leave) { + // It is guaranteed by the standard that conversion of boolean to integral type will result in either 0 or 1 + r1::exit_parallel_phase(nullptr, static_cast(with_fast_leave)); +} +#endif + using r1::submit; } // namespace d1 @@ -491,6 +617,11 @@ using detail::d1::max_concurrency; using detail::d1::isolate; using detail::d1::enqueue; + +#if __TBB_PREVIEW_PARALLEL_PHASE +using detail::d1::start_parallel_phase; +using detail::d1::end_parallel_phase; +#endif } // namespace this_task_arena } // inline namespace v1 diff --git a/rfcs/proposed/parallel_block_for_task_arena/README.md b/rfcs/experimental/parallel_phase_for_task_arena/README.md similarity index 87% rename from rfcs/proposed/parallel_block_for_task_arena/README.md rename to rfcs/experimental/parallel_phase_for_task_arena/README.md index 207c318b4d..34f3cf877d 100644 --- a/rfcs/proposed/parallel_block_for_task_arena/README.md +++ b/rfcs/experimental/parallel_phase_for_task_arena/README.md @@ -235,7 +235,6 @@ void scoped_parallel_phase_example() { // Computation } } - ``` ## Considerations @@ -256,6 +255,32 @@ it might introduce performance problems if: Heavier involvement of less performant core types might result in artificial work imbalance in the arena. +## Technical Details + +To implement the proposed feature, the following changes were made: +* Added a new entity `thread_leave_manager` to the `r1::arena` which is responsible for + for managing the state of workers' arena leaving behaviour. +* Introduced two new entry points to the library. + * `r1::enter_parallel_phase(d1::task_arena_base*, std::uintptr_t)` - used to communicate + the start of parallel phase with the library. + * `r1::exit_parallel_phase(d1::task_arena_base*, std::uintptr_t)` - used to communicate + the end of parallel phase with the library. + +### Thread Leave Manager + +`thread_leave_manager` class implements the state machine described in proposal. +Specifically, it controls when worker threads are allowed to be retained in the arena. +`thread_leave_manager` is initialized with a state that determines the default +behavior for workers leaving the arena. + +To support `start/end_parallel_phase` API, it provides functionality to override the default +state with a "Parallel Phase" state. It also keeps track of the number of active parallel phases. + +The following sequence diagram illustrates the interaction between the user and +the `thread_leave_manager` during the execution of parallel phases. It shows how the +`thread_leave_manager` manages the state transitions when using `start/end_parallel_phase`. + + ## Open Questions in Design @@ -272,3 +297,10 @@ Some open questions that remain: * Do we see any value if arena potentially can transition from one to another state? * What if different types of workloads are mixed in one application? * What if there concurrent calls to this API? + +## Conditions to become fully supported + +Following conditions need to be met for the feature to move from experimental to fully supported: +* Open questions regarding API should be resolved. +* The feature should demonstrate performance improvements in scenarios mentioned. +* oneTBB specification needs to be updated to reflect the new feature. diff --git a/rfcs/proposed/parallel_block_for_task_arena/alternative_proposal.png b/rfcs/experimental/parallel_phase_for_task_arena/alternative_proposal.png similarity index 100% rename from rfcs/proposed/parallel_block_for_task_arena/alternative_proposal.png rename to rfcs/experimental/parallel_phase_for_task_arena/alternative_proposal.png diff --git a/rfcs/proposed/parallel_block_for_task_arena/completely_disable_new_behavior.png b/rfcs/experimental/parallel_phase_for_task_arena/completely_disable_new_behavior.png similarity index 100% rename from rfcs/proposed/parallel_block_for_task_arena/completely_disable_new_behavior.png rename to rfcs/experimental/parallel_phase_for_task_arena/completely_disable_new_behavior.png diff --git a/rfcs/proposed/parallel_block_for_task_arena/parallel_phase_introduction.png b/rfcs/experimental/parallel_phase_for_task_arena/parallel_phase_introduction.png similarity index 100% rename from rfcs/proposed/parallel_block_for_task_arena/parallel_phase_introduction.png rename to rfcs/experimental/parallel_phase_for_task_arena/parallel_phase_introduction.png diff --git a/rfcs/experimental/parallel_phase_for_task_arena/parallel_phase_sequence_diagram.png b/rfcs/experimental/parallel_phase_for_task_arena/parallel_phase_sequence_diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..24648722efc8b901befbcbaa1e0be26181b93b73 GIT binary patch literal 124339 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

ZgN0TLb#bo$F8PH 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 literal 0 HcmV?d00001 diff --git a/rfcs/proposed/parallel_block_for_task_arena/parallel_phase_state_final.png b/rfcs/experimental/parallel_phase_for_task_arena/parallel_phase_state_final.png similarity index 100% rename from rfcs/proposed/parallel_block_for_task_arena/parallel_phase_state_final.png rename to rfcs/experimental/parallel_phase_for_task_arena/parallel_phase_state_final.png diff --git a/rfcs/proposed/parallel_block_for_task_arena/parallel_phase_state_initial.png b/rfcs/experimental/parallel_phase_for_task_arena/parallel_phase_state_initial.png similarity index 100% rename from rfcs/proposed/parallel_block_for_task_arena/parallel_phase_state_initial.png rename to rfcs/experimental/parallel_phase_for_task_arena/parallel_phase_state_initial.png diff --git a/src/tbb/arena.cpp b/src/tbb/arena.cpp index 6ca062d02f..eb91ddf510 100644 --- a/src/tbb/arena.cpp +++ b/src/tbb/arena.cpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2005-2024 Intel Corporation + Copyright (c) 2005-2025 Intel Corporation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -241,7 +241,12 @@ void arena::process(thread_data& tls) { __TBB_ASSERT(tls.my_arena == this, "my_arena is used as a hint when searching the arena to join"); } -arena::arena(threading_control* control, unsigned num_slots, unsigned num_reserved_slots, unsigned priority_level) { +arena::arena(threading_control* control, unsigned num_slots, unsigned num_reserved_slots, unsigned priority_level +#if __TBB_PREVIEW_PARALLEL_PHASE + , tbb::task_arena::leave_policy lp +#endif +) +{ __TBB_ASSERT( !my_guard, "improperly allocated arena?" ); __TBB_ASSERT( sizeof(my_slots[0]) % cache_line_size()==0, "arena::slot size not multiple of cache line size" ); __TBB_ASSERT( is_aligned(this, cache_line_size()), "arena misaligned" ); @@ -276,10 +281,18 @@ arena::arena(threading_control* control, unsigned num_slots, unsigned num_reserv my_critical_task_stream.initialize(my_num_slots); #endif my_mandatory_requests = 0; + +#if __TBB_PREVIEW_PARALLEL_PHASE + my_thread_leave.set_initial_state(lp); +#endif } arena& arena::allocate_arena(threading_control* control, unsigned num_slots, unsigned num_reserved_slots, - unsigned priority_level) + unsigned priority_level +#if __TBB_PREVIEW_PARALLEL_PHASE + , tbb::task_arena::leave_policy lp +#endif +) { __TBB_ASSERT( sizeof(base_type) + sizeof(arena_slot) == sizeof(arena), "All arena data fields must go to arena_base" ); __TBB_ASSERT( sizeof(base_type) % cache_line_size() == 0, "arena slots area misaligned: wrong padding" ); @@ -290,7 +303,11 @@ arena& arena::allocate_arena(threading_control* control, unsigned num_slots, uns std::memset( storage, 0, n ); return *new( storage + num_arena_slots(num_slots, num_reserved_slots) * sizeof(mail_outbox) ) - arena(control, num_slots, num_reserved_slots, priority_level); + arena(control, num_slots, num_reserved_slots, priority_level +#if __TBB_PREVIEW_PARALLEL_PHASE + , lp +#endif + ); } void arena::free_arena () { @@ -443,11 +460,21 @@ void arena::enqueue_task(d1::task& t, d1::task_group_context& ctx, thread_data& advertise_new_work(); } -arena& arena::create(threading_control* control, unsigned num_slots, unsigned num_reserved_slots, unsigned arena_priority_level, d1::constraints constraints) { +arena &arena::create(threading_control *control, unsigned num_slots, + unsigned num_reserved_slots, unsigned arena_priority_level, + d1::constraints constraints +#if __TBB_PREVIEW_PARALLEL_PHASE + , tbb::task_arena::leave_policy lp +#endif +) { __TBB_ASSERT(num_slots > 0, NULL); __TBB_ASSERT(num_reserved_slots <= num_slots, NULL); // Add public market reference for an external thread/task_arena (that adds an internal reference in exchange). - arena& a = arena::allocate_arena(control, num_slots, num_reserved_slots, arena_priority_level); + arena& a = arena::allocate_arena(control, num_slots, num_reserved_slots, arena_priority_level +#if __TBB_PREVIEW_PARALLEL_PHASE + , lp +#endif + ); a.my_tc_client = control->create_client(a); // We should not publish arena until all fields are initialized control->publish_client(a.my_tc_client, constraints); @@ -500,6 +527,8 @@ struct task_arena_impl { static int max_concurrency(const d1::task_arena_base*); static void enqueue(d1::task&, d1::task_group_context*, d1::task_arena_base*); static d1::slot_id execution_slot(const d1::task_arena_base&); + static void enter_parallel_phase(d1::task_arena_base*, std::uintptr_t); + static void exit_parallel_phase(d1::task_arena_base*, std::uintptr_t); }; void __TBB_EXPORTED_FUNC initialize(d1::task_arena_base& ta) { @@ -534,6 +563,14 @@ d1::slot_id __TBB_EXPORTED_FUNC execution_slot(const d1::task_arena_base& arena) return task_arena_impl::execution_slot(arena); } +void __TBB_EXPORTED_FUNC enter_parallel_phase(d1::task_arena_base* ta, std::uintptr_t flags) { + task_arena_impl::enter_parallel_phase(ta, flags); +} + +void __TBB_EXPORTED_FUNC exit_parallel_phase(d1::task_arena_base* ta, std::uintptr_t flags) { + task_arena_impl::exit_parallel_phase(ta, flags); +} + void task_arena_impl::initialize(d1::task_arena_base& ta) { // Enforce global market initialization to properly initialize soft limit (void)governor::get_thread_data(); @@ -568,7 +605,12 @@ void task_arena_impl::initialize(d1::task_arena_base& ta) { __TBB_ASSERT(ta.my_arena.load(std::memory_order_relaxed) == nullptr, "Arena already initialized"); unsigned priority_level = arena_priority_level(ta.my_priority); threading_control* thr_control = threading_control::register_public_reference(); - arena& a = arena::create(thr_control, unsigned(ta.my_max_concurrency), ta.my_num_reserved_slots, priority_level, arena_constraints); + arena& a = arena::create(thr_control, unsigned(ta.my_max_concurrency), ta.my_num_reserved_slots, + priority_level, arena_constraints +#if __TBB_PREVIEW_PARALLEL_PHASE + , ta.get_leave_policy() +#endif + ); ta.my_arena.store(&a, std::memory_order_release); #if __TBB_CPUBIND_PRESENT @@ -875,6 +917,21 @@ int task_arena_impl::max_concurrency(const d1::task_arena_base *ta) { return int(governor::default_num_threads()); } +#if __TBB_PREVIEW_PARALLEL_PHASE +void task_arena_impl::enter_parallel_phase(d1::task_arena_base* ta, std::uintptr_t /*reserved*/) { + arena* a = ta ? ta->my_arena.load(std::memory_order_relaxed) : governor::get_thread_data()->my_arena; + __TBB_ASSERT(a, nullptr); + a->my_thread_leave.register_parallel_phase(); + a->advertise_new_work(); +} + +void task_arena_impl::exit_parallel_phase(d1::task_arena_base* ta, std::uintptr_t flags) { + arena* a = ta ? ta->my_arena.load(std::memory_order_relaxed) : governor::get_thread_data()->my_arena; + __TBB_ASSERT(a, nullptr); + a->my_thread_leave.unregister_parallel_phase(/*with_fast_leave=*/static_cast(flags)); +} +#endif + void isolate_within_arena(d1::delegate_base& d, std::intptr_t isolation) { // TODO: Decide what to do if the scheduler is not initialized. Is there a use case for it? thread_data* tls = governor::get_thread_data(); diff --git a/src/tbb/arena.h b/src/tbb/arena.h index 1e95f117b2..71aba8fa86 100644 --- a/src/tbb/arena.h +++ b/src/tbb/arena.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2005-2024 Intel Corporation + Copyright (c) 2005-2025 Intel Corporation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -179,6 +179,74 @@ class atomic_flag { } }; +#if __TBB_PREVIEW_PARALLEL_PHASE +class thread_leave_manager { + static const std::uintptr_t DELAYED_LEAVE = 0; + static const std::uintptr_t FAST_LEAVE = 1; + static const std::uintptr_t ONE_TIME_FAST_LEAVE = 1 << 1; + static const std::uintptr_t PARALLEL_PHASE = 1 << 2; + + std::atomic my_state{UINTPTR_MAX}; +public: + // This method is not thread-safe! + // Required to be called after construction to set initial state of the state machine. + void set_initial_state(tbb::task_arena::leave_policy lp) { + if (lp == tbb::task_arena::leave_policy::automatic) { + std::uintptr_t platform_policy = governor::hybrid_cpu() ? FAST_LEAVE : DELAYED_LEAVE; + my_state.store(platform_policy, std::memory_order_relaxed); + } else { + __TBB_ASSERT(lp == tbb::task_arena::leave_policy::fast, + "Was the new value introduced for leave policy?"); + my_state.store(FAST_LEAVE, std::memory_order_relaxed); + } + } + + void reset_if_needed() { + std::uintptr_t curr = my_state.load(std::memory_order_relaxed); + if (curr == ONE_TIME_FAST_LEAVE) { + // Potentially can override decision of the parallel phase from future epoch + // but it is not a problem because it does not violate the correctness + my_state.fetch_and(~ONE_TIME_FAST_LEAVE); + } + } + + // Indicate start of parallel phase in the state machine + void register_parallel_phase() { + __TBB_ASSERT(my_state.load(std::memory_order_relaxed) != UINTPTR_MAX, "The initial state was not set"); + + std::uintptr_t prev = my_state.fetch_add(PARALLEL_PHASE); + __TBB_ASSERT(prev + PARALLEL_PHASE > prev, "Overflow detected"); + if (prev & ONE_TIME_FAST_LEAVE) { + // State was previously transitioned to "One-time Fast leave", thus with the start + // of new parallel phase, it should be reset + my_state.fetch_and(~ONE_TIME_FAST_LEAVE); + } + } + + // Indicate the end of parallel phase in the state machine + void unregister_parallel_phase(bool enable_fast_leave) { + std::uintptr_t prev = my_state.load(std::memory_order_relaxed); + __TBB_ASSERT(prev != UINTPTR_MAX, "The initial state was not set"); + + std::uintptr_t desired{}; + do { + __TBB_ASSERT(prev - PARALLEL_PHASE < prev, + "A call to unregister without its register complement"); + desired = prev - PARALLEL_PHASE; // Mark the end of this phase in reference counter + if (enable_fast_leave && /*it was the last parallel phase*/desired == DELAYED_LEAVE) { + desired = ONE_TIME_FAST_LEAVE; + } + } while (!my_state.compare_exchange_strong(prev, desired)); + } + + bool is_retention_allowed() { + std::uintptr_t curr = my_state.load(std::memory_order_relaxed); + __TBB_ASSERT(curr != UINTPTR_MAX, "The initial state was not set"); + return curr != FAST_LEAVE && curr != ONE_TIME_FAST_LEAVE; + } +}; +#endif /* __TBB_PREVIEW_PARALLEL_PHASE */ + //! The structure of an arena, except the array of slots. /** Separated in order to simplify padding. Intrusive list node base class is used by market to form a list of arenas. **/ @@ -245,6 +313,11 @@ struct arena_base : padded { //! Waiting object for external threads that cannot join the arena. concurrent_monitor my_exit_monitors; +#if __TBB_PREVIEW_PARALLEL_PHASE + //! Manages state of thread_leave state machine + thread_leave_manager my_thread_leave; +#endif + //! Coroutines (task_dispathers) cache buffer arena_co_cache my_co_cache; @@ -281,13 +354,27 @@ class arena: public padded }; //! Constructor - arena(threading_control* control, unsigned max_num_workers, unsigned num_reserved_slots, unsigned priority_level); + arena(threading_control* control, unsigned max_num_workers, unsigned num_reserved_slots, unsigned priority_level +#if __TBB_PREVIEW_PARALLEL_PHASE + , tbb::task_arena::leave_policy lp +#endif + ); //! Allocate an instance of arena. static arena& allocate_arena(threading_control* control, unsigned num_slots, unsigned num_reserved_slots, - unsigned priority_level); + unsigned priority_level +#if __TBB_PREVIEW_PARALLEL_PHASE + , tbb::task_arena::leave_policy lp +#endif + ); - static arena& create(threading_control* control, unsigned num_slots, unsigned num_reserved_slots, unsigned arena_priority_level, d1::constraints constraints = d1::constraints{}); + static arena& create(threading_control* control, unsigned num_slots, unsigned num_reserved_slots, + unsigned arena_priority_level, + d1::constraints constraints = d1::constraints{} +#if __TBB_PREVIEW_PARALLEL_PHASE + , tbb::task_arena::leave_policy lp = tbb::task_arena::leave_policy::automatic +#endif + ); static int unsigned num_arena_slots ( unsigned num_slots, unsigned num_reserved_slots ) { return num_reserved_slots == 0 ? num_slots : max(2u, num_slots); @@ -433,6 +520,9 @@ void arena::advertise_new_work() { workers_delta = 1; } +#if __TBB_PREVIEW_PARALLEL_PHASE + my_thread_leave.reset_if_needed(); +#endif request_workers(mandatory_delta, workers_delta, /* wakeup_threads = */ true); } } diff --git a/src/tbb/def/lin32-tbb.def b/src/tbb/def/lin32-tbb.def index 737e8ec2af..da1dc0e626 100644 --- a/src/tbb/def/lin32-tbb.def +++ b/src/tbb/def/lin32-tbb.def @@ -1,5 +1,5 @@ /* - Copyright (c) 2005-2024 Intel Corporation + Copyright (c) 2005-2025 Intel Corporation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -107,6 +107,8 @@ _ZN3tbb6detail2r17enqueueERNS0_2d14taskEPNS2_15task_arena_baseE; _ZN3tbb6detail2r17enqueueERNS0_2d14taskERNS2_18task_group_contextEPNS2_15task_arena_baseE; _ZN3tbb6detail2r14waitERNS0_2d115task_arena_baseE; _ZN3tbb6detail2r114execution_slotERKNS0_2d115task_arena_baseE; +_ZN3tbb6detail2r119exit_parallel_phaseEPNS0_2d115task_arena_baseEj; +_ZN3tbb6detail2r120enter_parallel_phaseEPNS0_2d115task_arena_baseEj; /* System topology parsing and threads pinning (governor.cpp) */ _ZN3tbb6detail2r115numa_node_countEv; diff --git a/src/tbb/def/lin64-tbb.def b/src/tbb/def/lin64-tbb.def index 41aca2e932..b14e1c805b 100644 --- a/src/tbb/def/lin64-tbb.def +++ b/src/tbb/def/lin64-tbb.def @@ -1,5 +1,5 @@ /* - Copyright (c) 2005-2024 Intel Corporation + Copyright (c) 2005-2025 Intel Corporation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -107,6 +107,8 @@ _ZN3tbb6detail2r17enqueueERNS0_2d14taskEPNS2_15task_arena_baseE; _ZN3tbb6detail2r17enqueueERNS0_2d14taskERNS2_18task_group_contextEPNS2_15task_arena_baseE; _ZN3tbb6detail2r14waitERNS0_2d115task_arena_baseE; _ZN3tbb6detail2r114execution_slotERKNS0_2d115task_arena_baseE; +_ZN3tbb6detail2r119exit_parallel_phaseEPNS0_2d115task_arena_baseEm; +_ZN3tbb6detail2r120enter_parallel_phaseEPNS0_2d115task_arena_baseEm; /* System topology parsing and threads pinning (governor.cpp) */ _ZN3tbb6detail2r115numa_node_countEv; diff --git a/src/tbb/def/mac64-tbb.def b/src/tbb/def/mac64-tbb.def index 38bc48d30e..fff79a391d 100644 --- a/src/tbb/def/mac64-tbb.def +++ b/src/tbb/def/mac64-tbb.def @@ -1,4 +1,4 @@ -# Copyright (c) 2005-2024 Intel Corporation +# Copyright (c) 2005-2025 Intel Corporation # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -109,6 +109,8 @@ __ZN3tbb6detail2r17enqueueERNS0_2d14taskEPNS2_15task_arena_baseE __ZN3tbb6detail2r17enqueueERNS0_2d14taskERNS2_18task_group_contextEPNS2_15task_arena_baseE __ZN3tbb6detail2r14waitERNS0_2d115task_arena_baseE __ZN3tbb6detail2r114execution_slotERKNS0_2d115task_arena_baseE +__ZN3tbb6detail2r119exit_parallel_phaseEPNS0_2d115task_arena_baseEm +__ZN3tbb6detail2r120enter_parallel_phaseEPNS0_2d115task_arena_baseEm # System topology parsing and threads pinning (governor.cpp) __ZN3tbb6detail2r115numa_node_countEv diff --git a/src/tbb/def/win32-tbb.def b/src/tbb/def/win32-tbb.def index 94b5441701..516075afd0 100644 --- a/src/tbb/def/win32-tbb.def +++ b/src/tbb/def/win32-tbb.def @@ -1,4 +1,4 @@ -; Copyright (c) 2005-2024 Intel Corporation +; Copyright (c) 2005-2025 Intel Corporation ; ; Licensed under the Apache License, Version 2.0 (the "License"); ; you may not use this file except in compliance with the License. @@ -101,6 +101,8 @@ EXPORTS ?wait@r1@detail@tbb@@YAXAAVtask_arena_base@d1@23@@Z ?enqueue@r1@detail@tbb@@YAXAAVtask@d1@23@AAVtask_group_context@523@PAVtask_arena_base@523@@Z ?execution_slot@r1@detail@tbb@@YAGABVtask_arena_base@d1@23@@Z +?enter_parallel_phase@r1@detail@tbb@@YAXPAVtask_arena_base@d1@23@I@Z +?exit_parallel_phase@r1@detail@tbb@@YAXPAVtask_arena_base@d1@23@I@Z ; System topology parsing and threads pinning (governor.cpp) ?numa_node_count@r1@detail@tbb@@YAIXZ diff --git a/src/tbb/def/win64-tbb.def b/src/tbb/def/win64-tbb.def index 96bafc0163..80273f88a2 100644 --- a/src/tbb/def/win64-tbb.def +++ b/src/tbb/def/win64-tbb.def @@ -1,4 +1,4 @@ -; Copyright (c) 2005-2024 Intel Corporation +; Copyright (c) 2005-2025 Intel Corporation ; ; Licensed under the Apache License, Version 2.0 (the "License"); ; you may not use this file except in compliance with the License. @@ -101,6 +101,8 @@ EXPORTS ?enqueue@r1@detail@tbb@@YAXAEAVtask@d1@23@PEAVtask_arena_base@523@@Z ?enqueue@r1@detail@tbb@@YAXAEAVtask@d1@23@AEAVtask_group_context@523@PEAVtask_arena_base@523@@Z ?execution_slot@r1@detail@tbb@@YAGAEBVtask_arena_base@d1@23@@Z +?enter_parallel_phase@r1@detail@tbb@@YAXPEAVtask_arena_base@d1@23@_K@Z +?exit_parallel_phase@r1@detail@tbb@@YAXPEAVtask_arena_base@d1@23@_K@Z ; System topology parsing and threads pinning (governor.cpp) ?numa_node_count@r1@detail@tbb@@YAIXZ diff --git a/src/tbb/waiters.h b/src/tbb/waiters.h index 8ed431f857..5ec2710f31 100644 --- a/src/tbb/waiters.h +++ b/src/tbb/waiters.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2005-2024 Intel Corporation + Copyright (c) 2005-2025 Intel Corporation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -54,13 +54,14 @@ class outermost_worker_waiter : public waiter_base { public: using waiter_base::waiter_base; - bool continue_execution(arena_slot& slot, d1::task*& t) const { + bool continue_execution(arena_slot& slot, d1::task*& t) { __TBB_ASSERT(t == nullptr, nullptr); if (is_worker_should_leave(slot)) { - if (!governor::hybrid_cpu()) { + if (is_delayed_leave_enabled()) { static constexpr std::chrono::microseconds worker_wait_leave_duration(1000); - static_assert(worker_wait_leave_duration > std::chrono::steady_clock::duration(1), "Clock resolution is not enough for measured interval."); + static_assert(worker_wait_leave_duration > std::chrono::steady_clock::duration(1), + "Clock resolution is not enough for measured interval."); for (auto t1 = std::chrono::steady_clock::now(), t2 = t1; std::chrono::duration_cast(t2 - t1) < worker_wait_leave_duration; @@ -70,7 +71,9 @@ class outermost_worker_waiter : public waiter_base { return true; } - if (my_arena.my_threading_control->is_any_other_client_active()) { + if (!my_arena.my_thread_leave.is_retention_allowed() || + my_arena.my_threading_control->is_any_other_client_active()) + { break; } d0::yield(); @@ -100,6 +103,14 @@ class outermost_worker_waiter : public waiter_base { private: using base_type = waiter_base; + bool is_delayed_leave_enabled() { +#if __TBB_PREVIEW_PARALLEL_PHASE + return my_arena.my_thread_leave.is_retention_allowed(); +#else + return !governor::hybrid_cpu(); +#endif + } + bool is_worker_should_leave(arena_slot& slot) const { bool is_top_priority_arena = my_arena.is_top_priority(); bool is_task_pool_empty = slot.task_pool.load(std::memory_order_relaxed) == EmptyTaskPool; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 92d233f17f..7145034c08 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -418,6 +418,7 @@ if (TARGET TBB::tbb) tbb_add_test(SUBDIR tbb NAME test_task_group DEPENDENCIES TBB::tbb) tbb_add_test(SUBDIR tbb NAME test_concurrent_hash_map DEPENDENCIES TBB::tbb) tbb_add_test(SUBDIR tbb NAME test_task_arena DEPENDENCIES TBB::tbb) + tbb_add_test(SUBDIR tbb NAME test_parallel_phase DEPENDENCIES TBB::tbb) tbb_add_test(SUBDIR tbb NAME test_enumerable_thread_specific DEPENDENCIES TBB::tbb) tbb_add_test(SUBDIR tbb NAME test_concurrent_queue DEPENDENCIES TBB::tbb) tbb_add_test(SUBDIR tbb NAME test_resumable_tasks DEPENDENCIES TBB::tbb) diff --git a/test/common/config.h b/test/common/config.h index c7ff8ba63a..2330b2be8c 100644 --- a/test/common/config.h +++ b/test/common/config.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2005-2024 Intel Corporation + Copyright (c) 2005-2025 Intel Corporation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -39,6 +39,9 @@ #ifndef TBB_PREVIEW_ISOLATED_TASK_GROUP #define TBB_PREVIEW_ISOLATED_TASK_GROUP 1 #endif +#ifndef TBB_PREVIEW_PARALLEL_PHASE +#define TBB_PREVIEW_PARALLEL_PHASE 1 +#endif #endif #include "oneapi/tbb/detail/_config.h" diff --git a/test/tbb/test_parallel_phase.cpp b/test/tbb/test_parallel_phase.cpp new file mode 100644 index 0000000000..b8ba2be012 --- /dev/null +++ b/test/tbb/test_parallel_phase.cpp @@ -0,0 +1,343 @@ +/* + Copyright (c) 2025 Intel Corporation + + 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. +*/ + +//! \file test_parallel_phase.cpp +//! \brief Test for [preview] functionality + +#define TBB_PREVIEW_PARALLEL_PHASE 1 + +#include + +#include "common/test.h" +#include "common/utils.h" +#include "common/utils_concurrency_limit.h" +#include "common/spin_barrier.h" + +#include "tbb/task_arena.h" +#include "tbb/parallel_for.h" + +void active_wait_for(std::chrono::microseconds duration) { + for (auto t1 = std::chrono::steady_clock::now(), t2 = t1; + std::chrono::duration_cast(t2 - t1) < duration; + t2 = std::chrono::steady_clock::now()) + { + utils::doDummyWork(100); + } +} + +struct dummy_func { + void operator()() const { + } +}; + +template +std::size_t measure_median_start_time(tbb::task_arena* ta, const F1& start = F1{}, const F2& end = F2{}) { + std::size_t num_threads = ta ? ta->max_concurrency() : tbb::this_task_arena::max_concurrency(); + std::size_t num_runs = 500; + std::vector longest_start_times; + longest_start_times.reserve(num_runs); + + std::vector start_times(num_threads); + utils::SpinBarrier barrier(num_threads); + auto measure_start_time = [&] (std::size_t) { + start_times[tbb::this_task_arena::current_thread_index()] = std::chrono::steady_clock::now(); + barrier.wait(); + }; + + auto get_longest_start = [&] (std::chrono::steady_clock::time_point start_time) { + std::size_t longest_time = 0; + for (auto& time : start_times) { + auto diff = std::chrono::duration_cast(time - start_time); + longest_time = std::max(longest_time, std::size_t(diff.count())); + } + return longest_time; + }; + + auto work = [&] { + auto start_time = std::chrono::steady_clock::now(); + start(); + tbb::parallel_for(std::size_t(0), num_threads, measure_start_time, tbb::static_partitioner{}); + end(); + longest_start_times.push_back(get_longest_start(start_time)); + }; + + for (std::size_t i = 1; i < num_runs; ++i) { + if (ta) { + ta->execute(work); + } else { + work(); + } + active_wait_for(std::chrono::microseconds(i*2)); + } + return utils::median(longest_start_times.begin(), longest_start_times.end()); +} + +template +class start_time_collection_base { + friend Impl; +public: + start_time_collection_base(tbb::task_arena& ta, std::size_t ntrials) : + arena(&ta), num_trials(ntrials), start_times(ntrials) {} + + explicit start_time_collection_base(std::size_t ntrials) : + arena(nullptr), num_trials(ntrials), start_times(ntrials) {} + + std::vector measure() { + for (std::size_t i = 0; i < num_trials; ++i) { + std::size_t median_start_time = static_cast(this)->measure_impl(); + start_times[i] = median_start_time; + } + return start_times; + } +protected: + tbb::task_arena* arena; + std::size_t num_trials; + std::vector start_times; +}; + +class start_time_collection : public start_time_collection_base { + using base = start_time_collection_base; + using base::base; + friend base; + + std::size_t measure_impl() { + return measure_median_start_time(arena); + } +}; + +class start_time_collection_phase_wrapped + : public start_time_collection_base +{ + using base = start_time_collection_base; + using base::base; + friend base; + + std::size_t measure_impl() { + arena->start_parallel_phase(); + auto median_start_time = measure_median_start_time(arena); + arena->end_parallel_phase(/*with_fast_leave*/true); + return median_start_time; + } +}; + +class start_time_collection_scoped_phase_wrapped + : public start_time_collection_base +{ + using base = start_time_collection_base; + using base::base; + friend base; + + std::size_t measure_impl() { + tbb::task_arena::scoped_parallel_phase phase{*arena}; + auto median_start_time = measure_median_start_time(arena); + return median_start_time; + } +}; + +class start_time_collection_sequenced_phases + : public start_time_collection_base +{ + using base = start_time_collection_base; + friend base; + + bool with_fast_leave; + + std::size_t measure_impl() { + std::size_t median_start_time; + utils::SpinBarrier barrier; + auto body = [&] (std::size_t) { + barrier.wait(); + }; + if (arena) { + barrier.initialize(arena->max_concurrency()); + median_start_time = measure_median_start_time(arena, + [&] { + std::size_t num_threads = arena->max_concurrency(); + arena->start_parallel_phase(); + arena->execute([&] { + tbb::parallel_for(std::size_t(0), num_threads, body, tbb::static_partitioner{}); + }); + arena->end_parallel_phase(with_fast_leave); + } + ); + } else { + barrier.initialize(tbb::this_task_arena::max_concurrency()); + median_start_time = measure_median_start_time(arena, + [&] { + std::size_t num_threads = tbb::this_task_arena::max_concurrency(); + tbb::this_task_arena::start_parallel_phase(); + tbb::parallel_for(std::size_t(0), num_threads, body, tbb::static_partitioner{}); + tbb::this_task_arena::end_parallel_phase(with_fast_leave); + } + ); + } + return median_start_time; + } + +public: + start_time_collection_sequenced_phases(tbb::task_arena& ta, std::size_t ntrials, bool fast_leave = false) : + base(ta, ntrials), with_fast_leave(fast_leave) + {} + + explicit start_time_collection_sequenced_phases(std::size_t ntrials, bool fast_leave = false) : + base(ntrials), with_fast_leave(fast_leave) + {} +}; + +class start_time_collection_sequenced_scoped_phases + : public start_time_collection_base +{ + using base = start_time_collection_base; + friend base; + + bool with_fast_leave; + + std::size_t measure_impl() { + utils::SpinBarrier barrier{static_cast(arena->max_concurrency())}; + auto body = [&] (std::size_t) { + barrier.wait(); + }; + auto median_start_time = measure_median_start_time(arena, + [&] { + std::size_t num_threads = arena->max_concurrency(); + { + tbb::task_arena::scoped_parallel_phase phase{*arena, with_fast_leave}; + arena->execute([&] { + tbb::parallel_for(std::size_t(0), num_threads, body, tbb::static_partitioner{}); + }); + } + } + ); + return median_start_time; + } + +public: + start_time_collection_sequenced_scoped_phases(tbb::task_arena& ta, std::size_t ntrials, bool fast_leave = false) : + base(ta, ntrials), with_fast_leave(fast_leave) + {} + + explicit start_time_collection_sequenced_scoped_phases(std::size_t ntrials, bool fast_leave = false) : + base(ntrials), with_fast_leave(fast_leave) + {} +}; + +//! \brief \ref interface \ref requirement +TEST_CASE("Check that workers leave faster with leave_policy::fast") { + // Test measures workers start time, so no there is no point to + // measure it with workerless arena + if (utils::get_platform_max_threads() < 2) { + return; + } + tbb::task_arena ta_automatic_leave { + tbb::task_arena::automatic, 1, + tbb::task_arena::priority::normal, + tbb::task_arena::leave_policy::automatic + }; + tbb::task_arena ta_fast_leave { + tbb::task_arena::automatic, 1, + tbb::task_arena::priority::normal, + tbb::task_arena::leave_policy::fast + }; + start_time_collection st_collector1{ta_automatic_leave, /*num_trials=*/5}; + start_time_collection st_collector2{ta_fast_leave, /*num_trials=*/5}; + + auto times_automatic = st_collector1.measure(); + auto times_fast = st_collector2.measure(); + + auto median_automatic = utils::median(times_automatic.begin(), times_automatic.end()); + auto median_fast = utils::median(times_fast.begin(), times_fast.end()); + + WARN_MESSAGE(median_automatic < median_fast, + "Expected workers to start new work slower with fast leave policy"); +} + +//! \brief \ref interface \ref requirement +TEST_CASE("Parallel Phase retains workers in task_arena") { + if (utils::get_platform_max_threads() < 2) { + return; + } + tbb::task_arena ta_fast1 { + tbb::task_arena::automatic, 1, + tbb::task_arena::priority::normal, + tbb::task_arena::leave_policy::fast + }; + tbb::task_arena ta_fast2 { + tbb::task_arena::automatic, 1, + tbb::task_arena::priority::normal, + tbb::task_arena::leave_policy::fast + }; + start_time_collection_phase_wrapped st_collector1{ta_fast1, /*num_trials=*/5}; + start_time_collection_scoped_phase_wrapped st_collector_scoped{ta_fast1, /*num_trials=*/5}; + start_time_collection st_collector2{ta_fast2, /*num_trials=*/5}; + + auto times1 = st_collector1.measure(); + auto times2 = st_collector2.measure(); + auto times_scoped = st_collector_scoped.measure(); + + auto median1 = utils::median(times1.begin(), times1.end()); + auto median2 = utils::median(times2.begin(), times2.end()); + auto median_scoped = utils::median(times_scoped.begin(), times_scoped.end()); + + WARN_MESSAGE(median1 < median2, + "Expected workers start new work faster when using parallel_phase"); + + WARN_MESSAGE(median_scoped < median2, + "Expected workers start new work faster when using scoped parallel_phase"); +} + +//! \brief \ref interface \ref requirement +TEST_CASE("Test one-time fast leave") { + if (utils::get_platform_max_threads() < 2) { + return; + } + tbb::task_arena ta1{}; + tbb::task_arena ta2{}; + start_time_collection_sequenced_phases st_collector1{ta1, /*num_trials=*/10}; + start_time_collection_sequenced_phases st_collector2{ta2, /*num_trials=*/10, /*fast_leave*/true}; + start_time_collection_sequenced_scoped_phases st_collector_scoped{ta2, /*num_trials=*/10, /*fast_leave*/true}; + + auto times1 = st_collector1.measure(); + auto times2 = st_collector2.measure(); + auto times_scoped = st_collector_scoped.measure(); + + auto median1 = utils::median(times1.begin(), times1.end()); + auto median2 = utils::median(times2.begin(), times2.end()); + auto median_scoped = utils::median(times_scoped.begin(), times_scoped.end()); + + WARN_MESSAGE(median1 < median2, + "Expected one-time fast leave setting to slow workers to start new work"); + + WARN_MESSAGE(median1 < median_scoped, + "Expected one-time fast leave setting to slow workers to start new work"); +} + +//! \brief \ref interface \ref requirement +TEST_CASE("Test parallel phase with this_task_arena") { + if (utils::get_platform_max_threads() < 2) { + return; + } + start_time_collection_sequenced_phases st_collector1{/*num_trials=*/10}; + start_time_collection_sequenced_phases st_collector2{/*num_trials=*/10, /*fast_leave*/true}; + + auto times1 = st_collector1.measure(); + auto times2 = st_collector2.measure(); + + auto median1 = utils::median(times1.begin(), times1.end()); + auto median2 = utils::median(times2.begin(), times2.end()); + + WARN_MESSAGE(median1 < median2, + "Expected one-time fast leave setting to slow workers to start new work"); +}