Intel(R) Threading Building Blocks Doxygen Documentation  version 4.2.3
partitioner.h
Go to the documentation of this file.
1 /*
2  Copyright (c) 2005-2019 Intel Corporation
3 
4  Licensed under the Apache License, Version 2.0 (the "License");
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7 
8  http://www.apache.org/licenses/LICENSE-2.0
9 
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15 
16 
17 
18 
19 */
20 
21 #ifndef __TBB_partitioner_H
22 #define __TBB_partitioner_H
23 
24 #ifndef __TBB_INITIAL_CHUNKS
25 // initial task divisions per thread
26 #define __TBB_INITIAL_CHUNKS 2
27 #endif
28 #ifndef __TBB_RANGE_POOL_CAPACITY
29 // maximum number of elements in range pool
30 #define __TBB_RANGE_POOL_CAPACITY 8
31 #endif
32 #ifndef __TBB_INIT_DEPTH
33 // initial value for depth of range pool
34 #define __TBB_INIT_DEPTH 5
35 #endif
36 #ifndef __TBB_DEMAND_DEPTH_ADD
37 // when imbalance is found range splits this value times more
38 #define __TBB_DEMAND_DEPTH_ADD 1
39 #endif
40 #ifndef __TBB_STATIC_THRESHOLD
41 // necessary number of clocks for the work to be distributed among all tasks
42 #define __TBB_STATIC_THRESHOLD 40000
43 #endif
44 #if __TBB_DEFINE_MIC
45 #define __TBB_NONUNIFORM_TASK_CREATION 1
46 #ifdef __TBB_time_stamp
47 #define __TBB_USE_MACHINE_TIME_STAMPS 1
48 #define __TBB_task_duration() __TBB_STATIC_THRESHOLD
49 #endif // __TBB_machine_time_stamp
50 #endif // __TBB_DEFINE_MIC
51 
52 #include "task.h"
53 #include "task_arena.h"
54 #include "aligned_space.h"
55 #include "atomic.h"
57 
58 #if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
59  // Workaround for overzealous compiler warnings
60  #pragma warning (push)
61  #pragma warning (disable: 4244)
62 #endif
63 
64 namespace tbb {
65 
66 class auto_partitioner;
67 class simple_partitioner;
68 class static_partitioner;
69 class affinity_partitioner;
70 
71 namespace interface9 {
72  namespace internal {
73  class affinity_partition_type;
74  }
75 }
76 
77 namespace internal { //< @cond INTERNAL
79 
85 
88  size_t my_size;
90  affinity_partitioner_base_v3() : my_array(NULL), my_size(0) {}
94 
95  void __TBB_EXPORTED_METHOD resize( unsigned factor );
96 };
97 
100 public:
101  void set_affinity( task & ) {}
104  bool decide_whether_to_delay() {return false;}
105  void spawn_or_delay( bool, task& b ) {
106  task::spawn(b);
107  }
108 };
109 
110 template<typename Range, typename Body, typename Partitioner> class start_scan;
111 
112 } //< namespace internal @endcond
113 
114 namespace serial {
115 namespace interface9 {
116 template<typename Range, typename Body, typename Partitioner> class start_for;
117 }
118 }
119 
120 namespace interface9 {
122 namespace internal {
123 using namespace tbb::internal;
124 template<typename Range, typename Body, typename Partitioner> class start_for;
125 template<typename Range, typename Body, typename Partitioner> class start_reduce;
126 template<typename Range, typename Body, typename Partitioner> class start_deterministic_reduce;
127 
129 class flag_task: public task {
130 public:
132  flag_task() { my_child_stolen = false; }
133  task* execute() __TBB_override { return NULL; }
134  static void mark_task_stolen(task &t) {
135  tbb::atomic<bool> &flag = static_cast<flag_task*>(t.parent())->my_child_stolen;
136 #if TBB_USE_THREADING_TOOLS
137  // Threading tools respect lock prefix but report false-positive data-race via plain store
138  flag.fetch_and_store<release>(true);
139 #else
140  flag = true;
141 #endif //TBB_USE_THREADING_TOOLS
142  }
143  static bool is_peer_stolen(task &t) {
144  return static_cast<flag_task*>(t.parent())->my_child_stolen;
145  }
146 };
147 
151 typedef unsigned char depth_t;
152 
154 template <typename T, depth_t MaxCapacity>
156  depth_t my_head;
157  depth_t my_tail;
158  depth_t my_size;
159  depth_t my_depth[MaxCapacity]; // relative depths of stored ranges
161 
162 public:
164  range_vector(const T& elem) : my_head(0), my_tail(0), my_size(1) {
165  my_depth[0] = 0;
166  new( static_cast<void *>(my_pool.begin()) ) T(elem);//TODO: std::move?
167  }
169  while( !empty() ) pop_back();
170  }
171  bool empty() const { return my_size == 0; }
172  depth_t size() const { return my_size; }
175  void split_to_fill(depth_t max_depth) {
176  while( my_size < MaxCapacity && is_divisible(max_depth) ) {
177  depth_t prev = my_head;
178  my_head = (my_head + 1) % MaxCapacity;
179  new(my_pool.begin()+my_head) T(my_pool.begin()[prev]); // copy TODO: std::move?
180  my_pool.begin()[prev].~T(); // instead of assignment
181  new(my_pool.begin()+prev) T(my_pool.begin()[my_head], split()); // do 'inverse' split
182  my_depth[my_head] = ++my_depth[prev];
183  my_size++;
184  }
185  }
186  void pop_back() {
187  __TBB_ASSERT(my_size > 0, "range_vector::pop_back() with empty size");
188  my_pool.begin()[my_head].~T();
189  my_size--;
190  my_head = (my_head + MaxCapacity - 1) % MaxCapacity;
191  }
192  void pop_front() {
193  __TBB_ASSERT(my_size > 0, "range_vector::pop_front() with empty size");
194  my_pool.begin()[my_tail].~T();
195  my_size--;
196  my_tail = (my_tail + 1) % MaxCapacity;
197  }
198  T& back() {
199  __TBB_ASSERT(my_size > 0, "range_vector::back() with empty size");
200  return my_pool.begin()[my_head];
201  }
202  T& front() {
203  __TBB_ASSERT(my_size > 0, "range_vector::front() with empty size");
204  return my_pool.begin()[my_tail];
205  }
207  depth_t front_depth() {
208  __TBB_ASSERT(my_size > 0, "range_vector::front_depth() with empty size");
209  return my_depth[my_tail];
210  }
211  depth_t back_depth() {
212  __TBB_ASSERT(my_size > 0, "range_vector::back_depth() with empty size");
213  return my_depth[my_head];
214  }
215  bool is_divisible(depth_t max_depth) {
216  return back_depth() < max_depth && back().is_divisible();
217  }
218 };
219 
221 template <typename Partition>
223  typedef split split_type;
224  // decision makers
225  void set_affinity( task & ) {}
227  bool check_being_stolen(task &) { return false; } // part of old should_execute_range()
228  bool check_for_demand(task &) { return false; }
229  bool is_divisible() { return true; } // part of old should_execute_range()
230  depth_t max_depth() { return 0; }
231  void align_depth(depth_t) { }
232  template <typename Range> split_type get_split() { return split(); }
233  Partition& self() { return *static_cast<Partition*>(this); } // CRTP helper
234 
235  template<typename StartType, typename Range>
236  void work_balance(StartType &start, Range &range) {
237  start.run_body( range ); // simple partitioner goes always here
238  }
239 
240  template<typename StartType, typename Range>
241  void execute(StartType &start, Range &range) {
242  // The algorithm in a few words ([]-denotes calls to decision methods of partitioner):
243  // [If this task is stolen, adjust depth and divisions if necessary, set flag].
244  // If range is divisible {
245  // Spread the work while [initial divisions left];
246  // Create trap task [if necessary];
247  // }
248  // If not divisible or [max depth is reached], execute, else do the range pool part
249  if ( range.is_divisible() ) {
250  if ( self().is_divisible() ) {
251  do { // split until is divisible
252  typename Partition::split_type split_obj = self().template get_split<Range>();
253  start.offer_work( split_obj );
254  } while ( range.is_divisible() && self().is_divisible() );
255  }
256  }
257  self().work_balance(start, range);
258  }
259 };
260 
263 
266 template <typename Range>
268 private:
269  typedef char yes[1];
270  typedef char no[2];
271 
272  template <typename range_type> static yes& decide(typename enable_if<range_type::is_splittable_in_proportion>::type *);
273  template <typename range_type> static no& decide(...);
274 public:
275  // equals to 'true' if and only if static const variable 'is_splittable_in_proportion' of template parameter
276  // initialized with the value of 'true'
277  static const bool value = (sizeof(decide<Range>(0)) == sizeof(yes));
278 };
279 
281 template <typename Partition>
282 struct adaptive_mode : partition_type_base<Partition> {
283  typedef Partition my_partition;
284  size_t my_divisor;
285  // For affinity_partitioner, my_divisor indicates the number of affinity array indices the task reserves.
286  // A task which has only one index must produce the right split without reserved index in order to avoid
287  // it to be overwritten in note_affinity() of the created (right) task.
288  // I.e. a task created deeper than the affinity array can remember must not save its affinity (LIFO order)
289  static const unsigned factor = 1;
290  adaptive_mode() : my_divisor(tbb::internal::get_initial_auto_partitioner_divisor() / 4 * my_partition::factor) {}
291  adaptive_mode(adaptive_mode &src, split) : my_divisor(do_split(src, split())) {}
293  size_t do_split(adaptive_mode &src, split) {
294  return src.my_divisor /= 2u;
295  }
296 };
297 
299 template <typename Partition>
300 struct proportional_mode : adaptive_mode<Partition> {
301  typedef Partition my_partition;
302  using partition_type_base<Partition>::self; // CRTP helper to get access to derived classes
303 
304  proportional_mode() : adaptive_mode<Partition>() {}
306  proportional_mode(proportional_mode &src, const proportional_split& split_obj) { self().my_divisor = do_split(src, split_obj); }
307  size_t do_split(proportional_mode &src, const proportional_split& split_obj) {
308 #if __TBB_ENABLE_RANGE_FEEDBACK
309  size_t portion = size_t(float(src.my_divisor) * float(split_obj.right())
310  / float(split_obj.left() + split_obj.right()) + 0.5f);
311 #else
312  size_t portion = split_obj.right() * my_partition::factor;
313 #endif
314  portion = (portion + my_partition::factor/2) & (0ul - my_partition::factor);
315 #if __TBB_ENABLE_RANGE_FEEDBACK
316 
317  if (!portion)
318  portion = my_partition::factor;
319  else if (portion == src.my_divisor)
320  portion = src.my_divisor - my_partition::factor;
321 #endif
322  src.my_divisor -= portion;
323  return portion;
324  }
325  bool is_divisible() { // part of old should_execute_range()
326  return self().my_divisor > my_partition::factor;
327  }
328 #if _MSC_VER && !defined(__INTEL_COMPILER)
329  // Suppress "conditional expression is constant" warning.
330  #pragma warning( push )
331  #pragma warning( disable: 4127 )
332 #endif
333  template <typename Range>
336  size_t size = self().my_divisor / my_partition::factor;
337 #if __TBB_NONUNIFORM_TASK_CREATION
338  size_t right = (size + 2) / 3;
339 #else
340  size_t right = size / 2;
341 #endif
342  size_t left = size - right;
343  return proportional_split(left, right);
344  } else {
345  return proportional_split(1, 1);
346  }
347  }
348 #if _MSC_VER && !defined(__INTEL_COMPILER)
349  #pragma warning( pop )
350 #endif // warning 4127 is back
351 };
352 
353 static size_t get_initial_partition_head() {
354  int current_index = tbb::this_task_arena::current_thread_index();
355  if (current_index == tbb::task_arena::not_initialized)
356  current_index = 0;
357  return size_t(current_index);
358 }
359 
361 template <typename Partition>
363  size_t my_head;
367  my_max_affinity(self().my_divisor) {}
369  , my_head((src.my_head + src.my_divisor) % src.my_max_affinity), my_max_affinity(src.my_max_affinity) {}
370  linear_affinity_mode(linear_affinity_mode &src, const proportional_split& split_obj) : proportional_mode<Partition>(src, split_obj)
371  , my_head((src.my_head + src.my_divisor) % src.my_max_affinity), my_max_affinity(src.my_max_affinity) {}
372  void set_affinity( task &t ) {
373  if( self().my_divisor )
374  t.set_affinity( affinity_id(my_head) + 1 );
375  }
376 };
377 
379 template<class Mode>
380 struct dynamic_grainsize_mode : Mode {
381  using Mode::self;
382 #ifdef __TBB_USE_MACHINE_TIME_STAMPS
383  tbb::internal::machine_tsc_t my_dst_tsc;
384 #endif
385  enum {
386  begin = 0,
388  pass
389  } my_delay;
390  depth_t my_max_depth;
391  static const unsigned range_pool_size = __TBB_RANGE_POOL_CAPACITY;
393 #ifdef __TBB_USE_MACHINE_TIME_STAMPS
394  , my_dst_tsc(0)
395 #endif
396  , my_delay(begin)
397  , my_max_depth(__TBB_INIT_DEPTH) {}
399  : Mode(p, split())
400 #ifdef __TBB_USE_MACHINE_TIME_STAMPS
401  , my_dst_tsc(0)
402 #endif
403  , my_delay(pass)
404  , my_max_depth(p.my_max_depth) {}
406  : Mode(p, split_obj)
407 #ifdef __TBB_USE_MACHINE_TIME_STAMPS
408  , my_dst_tsc(0)
409 #endif
410  , my_delay(begin)
411  , my_max_depth(p.my_max_depth) {}
412  bool check_being_stolen( task &t) { // part of old should_execute_range()
413  if( !(self().my_divisor / Mode::my_partition::factor) ) { // if not from the top P tasks of binary tree
414  self().my_divisor = 1; // TODO: replace by on-stack flag (partition_state's member)?
415  if( t.is_stolen_task() && t.parent()->ref_count() >= 2 ) { // runs concurrently with the left task
416 #if __TBB_USE_OPTIONAL_RTTI
417  // RTTI is available, check whether the cast is valid
418  __TBB_ASSERT(dynamic_cast<flag_task*>(t.parent()), 0);
419  // correctness of the cast relies on avoiding the root task for which:
420  // - initial value of my_divisor != 0 (protected by separate assertion)
421  // - is_stolen_task() always returns false for the root task.
422 #endif
424  if( !my_max_depth ) my_max_depth++;
425  my_max_depth += __TBB_DEMAND_DEPTH_ADD;
426  return true;
427  }
428  }
429  return false;
430  }
431  depth_t max_depth() { return my_max_depth; }
432  void align_depth(depth_t base) {
433  __TBB_ASSERT(base <= my_max_depth, 0);
434  my_max_depth -= base;
435  }
436  template<typename StartType, typename Range>
437  void work_balance(StartType &start, Range &range) {
438  if( !range.is_divisible() || !self().max_depth() ) {
439  start.run_body( range ); // simple partitioner goes always here
440  }
441  else { // do range pool
442  internal::range_vector<Range, range_pool_size> range_pool(range);
443  do {
444  range_pool.split_to_fill(self().max_depth()); // fill range pool
445  if( self().check_for_demand( start ) ) {
446  if( range_pool.size() > 1 ) {
447  start.offer_work( range_pool.front(), range_pool.front_depth() );
448  range_pool.pop_front();
449  continue;
450  }
451  if( range_pool.is_divisible(self().max_depth()) ) // was not enough depth to fork a task
452  continue; // note: next split_to_fill() should split range at least once
453  }
454  start.run_body( range_pool.back() );
455  range_pool.pop_back();
456  } while( !range_pool.empty() && !start.is_cancelled() );
457  }
458  }
459  bool check_for_demand( task &t ) {
460  if( pass == my_delay ) {
461  if( self().my_divisor > 1 ) // produce affinitized tasks while they have slot in array
462  return true; // do not do my_max_depth++ here, but be sure range_pool is splittable once more
463  else if( self().my_divisor && my_max_depth ) { // make balancing task
464  self().my_divisor = 0; // once for each task; depth will be decreased in align_depth()
465  return true;
466  }
467  else if( flag_task::is_peer_stolen(t) ) {
468  my_max_depth += __TBB_DEMAND_DEPTH_ADD;
469  return true;
470  }
471  } else if( begin == my_delay ) {
472 #ifndef __TBB_USE_MACHINE_TIME_STAMPS
473  my_delay = pass;
474 #else
475  my_dst_tsc = __TBB_time_stamp() + __TBB_task_duration();
476  my_delay = run;
477  } else if( run == my_delay ) {
478  if( __TBB_time_stamp() < my_dst_tsc ) {
479  __TBB_ASSERT(my_max_depth > 0, NULL);
480  my_max_depth--; // increase granularity since tasks seem having too small work
481  return false;
482  }
483  my_delay = pass;
484  return true;
485 #endif // __TBB_USE_MACHINE_TIME_STAMPS
486  }
487  return false;
488  }
489 };
490 
491 class auto_partition_type: public dynamic_grainsize_mode<adaptive_mode<auto_partition_type> > {
492 public:
495  my_divisor *= __TBB_INITIAL_CHUNKS;
496  }
499  bool is_divisible() { // part of old should_execute_range()
500  if( my_divisor > 1 ) return true;
501  if( my_divisor && my_max_depth ) { // can split the task. TODO: on-stack flag instead
502  // keep same fragmentation while splitting for the local task pool
503  my_max_depth--;
504  my_divisor = 0; // decrease max_depth once per task
505  return true;
506  } else return false;
507  }
509  if( flag_task::is_peer_stolen(t) ) {
510  my_max_depth += __TBB_DEMAND_DEPTH_ADD;
511  return true;
512  } else return false;
513  }
514 };
515 
516 class simple_partition_type: public partition_type_base<simple_partition_type> {
517 public:
521  template<typename StartType, typename Range>
522  void execute(StartType &start, Range &range) {
523  split_type split_obj = split(); // start.offer_work accepts split_type as reference
524  while( range.is_divisible() )
525  start.offer_work( split_obj );
526  start.run_body( range );
527  }
528 };
529 
530 class static_partition_type : public linear_affinity_mode<static_partition_type> {
531 public:
538  : linear_affinity_mode<static_partition_type>(p, split_obj) {}
539 };
540 
541 class affinity_partition_type : public dynamic_grainsize_mode<linear_affinity_mode<affinity_partition_type> > {
542  static const unsigned factor_power = 4; // TODO: get a unified formula based on number of computing units
544 public:
545  static const unsigned factor = 1 << factor_power; // number of slots in affinity array per task
549  __TBB_ASSERT( (factor&(factor-1))==0, "factor must be power of two" );
550  ap.resize(factor);
551  my_array = ap.my_array;
552  my_max_depth = factor_power + 1;
553  __TBB_ASSERT( my_max_depth < __TBB_RANGE_POOL_CAPACITY, 0 );
554  }
557  , my_array(p.my_array) {}
560  , my_array(p.my_array) {}
561  void set_affinity( task &t ) {
562  if( my_divisor ) {
563  if( !my_array[my_head] )
564  // TODO: consider new ideas with my_array for both affinity and static partitioner's, then code reuse
565  t.set_affinity( affinity_id(my_head / factor + 1) );
566  else
567  t.set_affinity( my_array[my_head] );
568  }
569  }
571  if( my_divisor )
572  my_array[my_head] = id;
573  }
574 };
575 
578  size_t num_chunks;
579  static const size_t VICTIM_CHUNKS = 4;
580 public:
581  bool should_execute_range(const task &t) {
582  if( num_chunks<VICTIM_CHUNKS && t.is_stolen_task() )
583  num_chunks = VICTIM_CHUNKS;
584  return num_chunks==1;
585  }
587  : num_chunks(internal::get_initial_auto_partitioner_divisor()*__TBB_INITIAL_CHUNKS/4) {}
589  : num_chunks(internal::get_initial_auto_partitioner_divisor()*__TBB_INITIAL_CHUNKS/4) {}
591  num_chunks = pt.num_chunks = (pt.num_chunks+1u) / 2u;
592  }
593 };
594 
595 } // namespace interfaceX::internal
597 } // namespace interfaceX
598 
600 
603 public:
605 private:
606  template<typename Range, typename Body, typename Partitioner> friend class serial::interface9::start_for;
607  template<typename Range, typename Body, typename Partitioner> friend class interface9::internal::start_for;
608  template<typename Range, typename Body, typename Partitioner> friend class interface9::internal::start_reduce;
609  template<typename Range, typename Body, typename Partitioner> friend class interface9::internal::start_deterministic_reduce;
610  template<typename Range, typename Body, typename Partitioner> friend class internal::start_scan;
611  // backward compatibility
612  class partition_type: public internal::partition_type_base {
613  public:
614  bool should_execute_range(const task& ) {return false;}
617  };
618  // new implementation just extends existing interface
620 
621  // TODO: consider to make split_type public
622  typedef interface9::internal::simple_partition_type::split_type split_type;
623 };
624 
626 
630 public:
632 
633 private:
634  template<typename Range, typename Body, typename Partitioner> friend class serial::interface9::start_for;
635  template<typename Range, typename Body, typename Partitioner> friend class interface9::internal::start_for;
636  template<typename Range, typename Body, typename Partitioner> friend class interface9::internal::start_reduce;
637  template<typename Range, typename Body, typename Partitioner> friend class internal::start_scan;
638  // backward compatibility
640  // new implementation just extends existing interface
642 
643  // TODO: consider to make split_type public
644  typedef interface9::internal::auto_partition_type::split_type split_type;
645 };
646 
649 public:
651 private:
652  template<typename Range, typename Body, typename Partitioner> friend class serial::interface9::start_for;
653  template<typename Range, typename Body, typename Partitioner> friend class interface9::internal::start_for;
654  template<typename Range, typename Body, typename Partitioner> friend class interface9::internal::start_reduce;
655  template<typename Range, typename Body, typename Partitioner> friend class interface9::internal::start_deterministic_reduce;
656  template<typename Range, typename Body, typename Partitioner> friend class internal::start_scan;
657  // backward compatibility
659  // new implementation just extends existing interface
661 
662  // TODO: consider to make split_type public
664 };
665 
667 class affinity_partitioner: internal::affinity_partitioner_base_v3 {
668 public:
670 
671 private:
672  template<typename Range, typename Body, typename Partitioner> friend class serial::interface9::start_for;
673  template<typename Range, typename Body, typename Partitioner> friend class interface9::internal::start_for;
674  template<typename Range, typename Body, typename Partitioner> friend class interface9::internal::start_reduce;
675  template<typename Range, typename Body, typename Partitioner> friend class internal::start_scan;
676  // backward compatibility - for parallel_scan only
678  // new implementation just extends existing interface
680 
681  // TODO: consider to make split_type public
683 };
684 
685 } // namespace tbb
686 
687 #if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
688  #pragma warning (pop)
689 #endif // warning 4244 is back
690 #undef __TBB_INITIAL_CHUNKS
691 #undef __TBB_RANGE_POOL_CAPACITY
692 #undef __TBB_INIT_DEPTH
693 #endif /* __TBB_partitioner_H */
#define __TBB_time_stamp()
A static partitioner.
Definition: partitioner.h:648
linear_affinity_mode(linear_affinity_mode &src, split)
Definition: partitioner.h:368
size_t do_split(adaptive_mode &src, split)
Definition: partitioner.h:293
#define __TBB_override
Definition: tbb_stddef.h:244
Provides backward-compatible methods for partition objects without affinity.
Definition: partitioner.h:99
unsigned short affinity_id
An id as used for specifying affinity.
Definition: task.h:124
T * begin() const
Pointer to beginning of array.
Definition: aligned_space.h:39
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id id
~affinity_partitioner_base_v3()
Deallocates my_array.
Definition: partitioner.h:92
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
void spawn_or_delay(bool, task &b)
Definition: partitioner.h:105
adaptive_mode(adaptive_mode &src, split)
Definition: partitioner.h:291
affinity_partitioner_base_v3()
Zeros the fields.
Definition: partitioner.h:90
static bool is_peer_stolen(task &t)
Definition: partitioner.h:143
Task type used to split the work of parallel_deterministic_reduce.
proportional_mode(proportional_mode &src, const proportional_split &split_obj)
Definition: partitioner.h:306
simple_partition_type(const simple_partitioner &)
Definition: partitioner.h:518
size_t right() const
Definition: tbb_stddef.h:414
Provides default splitting strategy for partition objects.
Definition: partitioner.h:282
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp begin
void execute(StartType &start, Range &range)
Definition: partitioner.h:241
Range pool stores ranges of type T in a circular buffer with MaxCapacity.
Definition: partitioner.h:155
Backward-compatible partition for auto and affinity partition objects.
Definition: partitioner.h:577
static void mark_task_stolen(task &t)
Definition: partitioner.h:134
Type enables transmission of splitting proportion from partitioners to range objects.
Definition: tbb_stddef.h:409
Provides default linear indexing of partitioner&#39;s sequence.
Definition: partitioner.h:362
internal::affinity_id affinity_id
An id as used for specifying affinity.
Definition: task.h:879
void split_to_fill(depth_t max_depth)
Definition: partitioner.h:175
affinity_partition_type(tbb::internal::affinity_partitioner_base_v3 &ap)
Definition: partitioner.h:547
interface9::internal::static_partition_type task_partition_type
Definition: partitioner.h:660
partition_type(const partition_type &, split)
Definition: partitioner.h:616
size_t left() const
Definition: tbb_stddef.h:413
interface9::internal::old_auto_partition_type partition_type
Definition: partitioner.h:677
Initial task to split the work.
range_vector(const T &elem)
initialize via first range in pool
Definition: partitioner.h:164
dynamic_grainsize_mode(dynamic_grainsize_mode &p, const proportional_split &split_obj)
Definition: partitioner.h:405
void const char const char int ITT_FORMAT __itt_group_sync p
auto_partition_type(const auto_partitioner &)
Definition: partitioner.h:493
#define __TBB_RANGE_POOL_CAPACITY
Definition: partitioner.h:30
partition_type(const simple_partitioner &)
Definition: partitioner.h:615
bool is_stolen_task() const
True if task was stolen from the task pool of another thread.
Definition: task.h:850
int ref_count() const
The internal reference count.
Definition: task.h:862
void __TBB_EXPORTED_METHOD resize(unsigned factor)
Resize my_array.
Definition: task.cpp:161
depth_t front_depth()
similarly to front(), returns depth of the first range in the pool
Definition: partitioner.h:207
#define __TBB_EXPORTED_METHOD
Definition: tbb_stddef.h:102
#define __TBB_INIT_DEPTH
Definition: partitioner.h:34
old_auto_partition_type(const affinity_partitioner &)
Definition: partitioner.h:588
tbb::atomic< bool > my_child_stolen
Definition: partitioner.h:131
interface9::internal::affinity_partition_type::split_type split_type
Definition: partitioner.h:682
uint64_t machine_tsc_t
dynamic_grainsize_mode(dynamic_grainsize_mode &p, split)
Definition: partitioner.h:398
static_partition_type(const static_partitioner &)
Definition: partitioner.h:533
interface9::internal::static_partition_type::split_type split_type
Definition: partitioner.h:663
static_partition_type(static_partition_type &p, split)
Definition: partitioner.h:535
static size_t get_initial_partition_head()
Definition: partitioner.h:353
The graph class.
auto_partition_type(auto_partition_type &src, split)
Definition: partitioner.h:497
interface9::internal::affinity_partition_type task_partition_type
Definition: partitioner.h:679
Task type used in parallel_for.
affinity_partition_type(affinity_partition_type &p, split)
Definition: partitioner.h:555
An auto partitioner.
Definition: partitioner.h:629
size_t do_split(proportional_mode &src, const proportional_split &split_obj)
Definition: partitioner.h:307
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long value
task * parent() const
task on whose behalf this task is working, or NULL if this is a root.
Definition: task.h:830
void work_balance(StartType &start, Range &range)
Definition: partitioner.h:236
Defines entry point for affinity partitioner into tbb run-time library.
Definition: partitioner.h:81
interface9::internal::simple_partition_type task_partition_type
Definition: partitioner.h:619
#define __TBB_EXPORTED_FUNC
interface9::internal::simple_partition_type::split_type split_type
Definition: partitioner.h:622
size_t __TBB_EXPORTED_FUNC get_initial_auto_partitioner_divisor()
Definition: task.cpp:153
value_type fetch_and_store(value_type value)
Definition: atomic.h:278
void note_affinity(task::affinity_id)
Definition: partitioner.h:102
size_t my_size
Number of elements in my_array.
Definition: partitioner.h:88
void work_balance(StartType &start, Range &range)
Definition: partitioner.h:437
#define __TBB_DEMAND_DEPTH_ADD
Definition: partitioner.h:38
task * execute() __TBB_override
Should be overridden by derived classes.
Definition: partitioner.h:133
void execute(StartType &start, Range &range)
simplified algorithm
Definition: partitioner.h:522
Join task node that contains shared flag for stealing feedback.
Definition: partitioner.h:129
bool is_divisible(depth_t max_depth)
Definition: partitioner.h:215
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t size
Base class for user-defined tasks.
Definition: task.h:592
interface9::internal::old_auto_partition_type partition_type
Definition: partitioner.h:639
int current_thread_index()
Returns the index, aka slot number, of the calling thread in its current arena.
Definition: task_arena.h:406
interface9::internal::old_auto_partition_type partition_type
Definition: partitioner.h:658
void set_affinity(affinity_id id)
Set affinity for this task.
Definition: task.h:882
affinity_id * my_array
Array that remembers affinities of tree positions to affinity_id.
Definition: partitioner.h:86
Dummy type that distinguishes splitting constructor from copy constructor.
Definition: tbb_stddef.h:399
An affinity partitioner.
Definition: partitioner.h:667
Task type used to split the work of parallel_reduce.
Provides proportional splitting strategy for partition objects.
Definition: partitioner.h:300
#define __TBB_INITIAL_CHUNKS
Definition: partitioner.h:26
Base class for types that should not be copied or assigned.
Definition: tbb_stddef.h:335
Identifiers declared inside namespace internal should never be used directly by client code...
Definition: atomic.h:55
tbb::aligned_space< T, MaxCapacity > my_pool
Definition: partitioner.h:160
Release.
Definition: atomic.h:49
proportional_mode(proportional_mode &src, split)
Definition: partitioner.h:305
linear_affinity_mode(linear_affinity_mode &src, const proportional_split &split_obj)
Definition: partitioner.h:370
interface9::internal::auto_partition_type::split_type split_type
Definition: partitioner.h:644
A simple partitioner.
Definition: partitioner.h:602
affinity_partition_type(affinity_partition_type &p, const proportional_split &split_obj)
Definition: partitioner.h:558
Enables one or the other code branches.
old_auto_partition_type(old_auto_partition_type &pt, split)
Definition: partitioner.h:590
simple_partition_type(const simple_partition_type &, split)
Definition: partitioner.h:519
interface9::internal::auto_partition_type task_partition_type
Definition: partitioner.h:641
static_partition_type(static_partition_type &p, const proportional_split &split_obj)
Definition: partitioner.h:537

Copyright © 2005-2019 Intel Corporation. All Rights Reserved.

Intel, Pentium, Intel Xeon, Itanium, Intel XScale and VTune are registered trademarks or trademarks of Intel Corporation or its subsidiaries in the United States and other countries.

* Other names and brands may be claimed as the property of others.