1616
1717#define TBB_PREVIEW_PARALLEL_PHASE 1
1818
19+ #include < chrono>
20+
1921#include " common/test.h"
2022#include " common/utils.h"
2123#include " common/utils_concurrency_limit.h"
2426#include " tbb/task_arena.h"
2527#include " tbb/parallel_for.h"
2628
29+ void active_wait_for (std::chrono::microseconds duration) {
30+ for (auto t1 = std::chrono::steady_clock::now (), t2 = t1;
31+ std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1) < duration;
32+ t2 = std::chrono::steady_clock::now ())
33+ {
34+ utils::doDummyWork (100 );
35+ }
36+ }
37+
2738struct dummy_func {
2839 void operator ()() const {
2940 }
@@ -66,7 +77,7 @@ std::size_t measure_median_start_time(tbb::task_arena* ta, const F1& start = F1{
6677 } else {
6778 work ();
6879 }
69- utils::doDummyWork (i* 250 );
80+ active_wait_for ( std::chrono::microseconds (i) );
7081 }
7182 return utils::median (longest_start_times.begin (), longest_start_times.end ());
7283}
@@ -101,7 +112,7 @@ class start_time_collection : public start_time_collection_base<start_time_colle
101112
102113 std::size_t measure_impl () {
103114 return measure_median_start_time (arena);
104- };
115+ }
105116};
106117
107118class start_time_collection_phase_wrapped
@@ -116,7 +127,7 @@ class start_time_collection_phase_wrapped
116127 auto median_start_time = measure_median_start_time (arena);
117128 arena->end_parallel_phase (/* with_fast_leave*/ true );
118129 return median_start_time;
119- };
130+ }
120131};
121132
122133class start_time_collection_scoped_phase_wrapped
@@ -130,7 +141,7 @@ class start_time_collection_scoped_phase_wrapped
130141 tbb::task_arena::scoped_parallel_phase phase{*arena};
131142 auto median_start_time = measure_median_start_time (arena);
132143 return median_start_time;
133- };
144+ }
134145};
135146
136147class start_time_collection_sequenced_phases
@@ -143,17 +154,35 @@ class start_time_collection_sequenced_phases
143154
144155 std::size_t measure_impl () {
145156 std::size_t median_start_time;
157+ utils::SpinBarrier barrier;
158+ auto body = [&] (std::size_t ) {
159+ barrier.wait ();
160+ };
146161 if (arena) {
162+ barrier.initialize (arena->max_concurrency ());
147163 median_start_time = measure_median_start_time (arena,
148- [this ] { arena->start_parallel_phase (); },
149- [this ] { arena->end_parallel_phase (with_fast_leave); });
164+ [&] {
165+ std::size_t num_threads = arena->max_concurrency ();
166+ arena->start_parallel_phase ();
167+ arena->execute ([&] {
168+ tbb::parallel_for (std::size_t (0 ), num_threads, body, tbb::static_partitioner{});
169+ });
170+ arena->end_parallel_phase (with_fast_leave);
171+ }
172+ );
150173 } else {
174+ barrier.initialize (tbb::this_task_arena::max_concurrency ());
151175 median_start_time = measure_median_start_time (arena,
152- [] { tbb::this_task_arena::start_parallel_phase (); },
153- [this ] { tbb::this_task_arena::end_parallel_phase (with_fast_leave); });
176+ [&] {
177+ std::size_t num_threads = tbb::this_task_arena::max_concurrency ();
178+ tbb::this_task_arena::start_parallel_phase ();
179+ tbb::parallel_for (std::size_t (0 ), num_threads, body, tbb::static_partitioner{});
180+ tbb::this_task_arena::end_parallel_phase (with_fast_leave);
181+ }
182+ );
154183 }
155184 return median_start_time;
156- };
185+ }
157186
158187public:
159188 start_time_collection_sequenced_phases (tbb::task_arena& ta, std::size_t ntrials, bool fast_leave = false ) :
@@ -168,31 +197,38 @@ class start_time_collection_sequenced_phases
168197class start_time_collection_sequenced_scoped_phases
169198 : public start_time_collection_base<start_time_collection_sequenced_scoped_phases>
170199{
171- using base = start_time_collection_base<start_time_collection_sequenced_scoped_phases>;
172- friend base;
173-
174- bool with_fast_leave;
175-
176- std::size_t measure_impl () {
177- tbb::task_arena::scoped_parallel_phase* phase = nullptr ;
178- auto median_start_time = measure_median_start_time (arena,
179- [this , &phase] {
180- phase = new tbb::task_arena::scoped_parallel_phase{*arena, with_fast_leave};
181- },
182- [&phase] {
183- delete phase;
184- });
185- return median_start_time;
186- };
200+ using base = start_time_collection_base<start_time_collection_sequenced_scoped_phases>;
201+ friend base;
202+
203+ bool with_fast_leave;
204+
205+ std::size_t measure_impl () {
206+ utils::SpinBarrier barrier{static_cast <std::size_t >(arena->max_concurrency ())};
207+ auto body = [&] (std::size_t ) {
208+ barrier.wait ();
209+ };
210+ auto median_start_time = measure_median_start_time (arena,
211+ [&] {
212+ std::size_t num_threads = arena->max_concurrency ();
213+ {
214+ tbb::task_arena::scoped_parallel_phase phase{*arena, with_fast_leave};
215+ arena->execute ([&] {
216+ tbb::parallel_for (std::size_t (0 ), num_threads, body, tbb::static_partitioner{});
217+ });
218+ }
219+ }
220+ );
221+ return median_start_time;
222+ }
187223
188224public:
189- start_time_collection_sequenced_scoped_phases (tbb::task_arena& ta, std::size_t ntrials, bool fast_leave = false ) :
190- base (ta, ntrials), with_fast_leave(fast_leave)
191- {}
225+ start_time_collection_sequenced_scoped_phases (tbb::task_arena& ta, std::size_t ntrials, bool fast_leave = false ) :
226+ base (ta, ntrials), with_fast_leave(fast_leave)
227+ {}
192228
193- explicit start_time_collection_sequenced_scoped_phases (std::size_t ntrials, bool fast_leave = false ) :
194- base(ntrials), with_fast_leave(fast_leave)
195- {}
229+ explicit start_time_collection_sequenced_scoped_phases (std::size_t ntrials, bool fast_leave = false ) :
230+ base(ntrials), with_fast_leave(fast_leave)
231+ {}
196232};
197233
198234// ! \brief \ref interface \ref requirement
0 commit comments