Intel(R) Threading Building Blocks Doxygen Documentation version 4.2.3
tbb::interface9::internal::dynamic_grainsize_mode< Mode > Struct Template Reference

#include <partitioner.h>

Inheritance diagram for tbb::interface9::internal::dynamic_grainsize_mode< Mode >:
Collaboration diagram for tbb::interface9::internal::dynamic_grainsize_mode< Mode >:

Public Types

enum  { begin = 0 , run , pass }
 

Public Member Functions

 dynamic_grainsize_mode ()
 
 dynamic_grainsize_mode (dynamic_grainsize_mode &p, split)
 
 dynamic_grainsize_mode (dynamic_grainsize_mode &p, const proportional_split &split_obj)
 
bool check_being_stolen (task &t)
 
depth_t max_depth ()
 
void align_depth (depth_t base)
 
template<typename StartType , typename Range >
void work_balance (StartType &start, Range &range)
 
bool check_for_demand (task &t)
 

Public Attributes

enum tbb::interface9::internal::dynamic_grainsize_mode:: { ... }  my_delay
 
depth_t my_max_depth
 

Static Public Attributes

static const unsigned range_pool_size = __TBB_RANGE_POOL_CAPACITY
 

Detailed Description

template<class Mode>
struct tbb::interface9::internal::dynamic_grainsize_mode< Mode >

Determine work-balance phase implementing splitting & stealing actions

Definition at line 364 of file partitioner.h.

Member Enumeration Documentation

◆ anonymous enum

template<class Mode >
anonymous enum
Enumerator
begin 
run 
pass 

Definition at line 369 of file partitioner.h.

Constructor & Destructor Documentation

◆ dynamic_grainsize_mode() [1/3]

template<class Mode >
tbb::interface9::internal::dynamic_grainsize_mode< Mode >::dynamic_grainsize_mode ( )
inline

Definition at line 376 of file partitioner.h.

376 : Mode()
377#ifdef __TBB_USE_MACHINE_TIME_STAMPS
378 , my_dst_tsc(0)
379#endif
380 , my_delay(begin)
#define __TBB_INIT_DEPTH
Definition: partitioner.h:33

◆ dynamic_grainsize_mode() [2/3]

template<class Mode >
tbb::interface9::internal::dynamic_grainsize_mode< Mode >::dynamic_grainsize_mode ( dynamic_grainsize_mode< Mode > &  p,
split   
)
inline

Definition at line 382 of file partitioner.h.

383 : Mode(p, split())
384#ifdef __TBB_USE_MACHINE_TIME_STAMPS
385 , my_dst_tsc(0)
386#endif
387 , my_delay(pass)
388 , my_max_depth(p.my_max_depth) {}
void const char const char int ITT_FORMAT __itt_group_sync p

◆ dynamic_grainsize_mode() [3/3]

template<class Mode >
tbb::interface9::internal::dynamic_grainsize_mode< Mode >::dynamic_grainsize_mode ( dynamic_grainsize_mode< Mode > &  p,
const proportional_split split_obj 
)
inline

Definition at line 389 of file partitioner.h.

390 : Mode(p, split_obj)
391#ifdef __TBB_USE_MACHINE_TIME_STAMPS
392 , my_dst_tsc(0)
393#endif
394 , my_delay(begin)
395 , my_max_depth(p.my_max_depth) {}

Member Function Documentation

◆ align_depth()

template<class Mode >
void tbb::interface9::internal::dynamic_grainsize_mode< Mode >::align_depth ( depth_t  base)
inline

Definition at line 416 of file partitioner.h.

416 {
417 __TBB_ASSERT(base <= my_max_depth, 0);
418 my_max_depth -= base;
419 }
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:165

References __TBB_ASSERT, and tbb::interface9::internal::dynamic_grainsize_mode< Mode >::my_max_depth.

◆ check_being_stolen()

template<class Mode >
bool tbb::interface9::internal::dynamic_grainsize_mode< Mode >::check_being_stolen ( task t)
inline

Definition at line 396 of file partitioner.h.

396 { // part of old should_execute_range()
397 if( !(self().my_divisor / Mode::my_partition::factor) ) { // if not from the top P tasks of binary tree
398 self().my_divisor = 1; // TODO: replace by on-stack flag (partition_state's member)?
399 if( t.is_stolen_task() && t.parent()->ref_count() >= 2 ) { // runs concurrently with the left task
400#if __TBB_USE_OPTIONAL_RTTI
401 // RTTI is available, check whether the cast is valid
402 __TBB_ASSERT(dynamic_cast<flag_task*>(t.parent()), 0);
403 // correctness of the cast relies on avoiding the root task for which:
404 // - initial value of my_divisor != 0 (protected by separate assertion)
405 // - is_stolen_task() always returns false for the root task.
406#endif
408 if( !my_max_depth ) my_max_depth++;
410 return true;
411 }
412 }
413 return false;
414 }
#define __TBB_DEMAND_DEPTH_ADD
Definition: partitioner.h:37
static void mark_task_stolen(task &t)
Definition: partitioner.h:133

References __TBB_ASSERT, __TBB_DEMAND_DEPTH_ADD, tbb::task::is_stolen_task(), tbb::interface9::internal::flag_task::mark_task_stolen(), tbb::interface9::internal::dynamic_grainsize_mode< Mode >::my_max_depth, tbb::task::parent(), and tbb::task::ref_count().

Here is the call graph for this function:

◆ check_for_demand()

template<class Mode >
bool tbb::interface9::internal::dynamic_grainsize_mode< Mode >::check_for_demand ( task t)
inline

Definition at line 443 of file partitioner.h.

443 {
444 if( pass == my_delay ) {
445 if( self().my_divisor > 1 ) // produce affinitized tasks while they have slot in array
446 return true; // do not do my_max_depth++ here, but be sure range_pool is splittable once more
447 else if( self().my_divisor && my_max_depth ) { // make balancing task
448 self().my_divisor = 0; // once for each task; depth will be decreased in align_depth()
449 return true;
450 }
451 else if( flag_task::is_peer_stolen(t) ) {
453 return true;
454 }
455 } else if( begin == my_delay ) {
456#ifndef __TBB_USE_MACHINE_TIME_STAMPS
457 my_delay = pass;
458#else
459 my_dst_tsc = __TBB_time_stamp() + __TBB_task_duration();
460 my_delay = run;
461 } else if( run == my_delay ) {
462 if( __TBB_time_stamp() < my_dst_tsc ) {
463 __TBB_ASSERT(my_max_depth > 0, NULL);
464 my_max_depth--; // increase granularity since tasks seem having too small work
465 return false;
466 }
467 my_delay = pass;
468 return true;
469#endif // __TBB_USE_MACHINE_TIME_STAMPS
470 }
471 return false;
472 }
#define __TBB_time_stamp()
static bool is_peer_stolen(task &t)
Definition: partitioner.h:142

References __TBB_ASSERT, __TBB_DEMAND_DEPTH_ADD, __TBB_time_stamp, tbb::interface9::internal::dynamic_grainsize_mode< Mode >::begin, tbb::interface9::internal::flag_task::is_peer_stolen(), tbb::interface9::internal::dynamic_grainsize_mode< Mode >::my_delay, tbb::interface9::internal::dynamic_grainsize_mode< Mode >::my_max_depth, tbb::interface9::internal::dynamic_grainsize_mode< Mode >::pass, and tbb::interface9::internal::dynamic_grainsize_mode< Mode >::run.

Referenced by tbb::interface9::internal::dynamic_grainsize_mode< Mode >::work_balance().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ max_depth()

template<class Mode >
depth_t tbb::interface9::internal::dynamic_grainsize_mode< Mode >::max_depth ( )
inline

Definition at line 415 of file partitioner.h.

415{ return my_max_depth; }

References tbb::interface9::internal::dynamic_grainsize_mode< Mode >::my_max_depth.

Referenced by tbb::interface9::internal::dynamic_grainsize_mode< Mode >::work_balance().

Here is the caller graph for this function:

◆ work_balance()

template<class Mode >
template<typename StartType , typename Range >
void tbb::interface9::internal::dynamic_grainsize_mode< Mode >::work_balance ( StartType &  start,
Range &  range 
)
inline

Definition at line 421 of file partitioner.h.

421 {
422 if( !range.is_divisible() || !self().max_depth() ) {
423 start.run_body( range ); // simple partitioner goes always here
424 }
425 else { // do range pool
426 internal::range_vector<Range, range_pool_size> range_pool(range);
427 do {
428 range_pool.split_to_fill(self().max_depth()); // fill range pool
429 if( self().check_for_demand( start ) ) {
430 if( range_pool.size() > 1 ) {
431 start.offer_work( range_pool.front(), range_pool.front_depth() );
432 range_pool.pop_front();
433 continue;
434 }
435 if( range_pool.is_divisible(self().max_depth()) ) // was not enough depth to fork a task
436 continue; // note: next split_to_fill() should split range at least once
437 }
438 start.run_body( range_pool.back() );
439 range_pool.pop_back();
440 } while( !range_pool.empty() && !start.is_cancelled() );
441 }
442 }

References tbb::interface9::internal::range_vector< T, MaxCapacity >::back(), tbb::interface9::internal::dynamic_grainsize_mode< Mode >::check_for_demand(), tbb::interface9::internal::range_vector< T, MaxCapacity >::empty(), tbb::interface9::internal::range_vector< T, MaxCapacity >::front(), tbb::interface9::internal::range_vector< T, MaxCapacity >::front_depth(), tbb::interface9::internal::range_vector< T, MaxCapacity >::is_divisible(), tbb::interface9::internal::dynamic_grainsize_mode< Mode >::max_depth(), tbb::interface9::internal::range_vector< T, MaxCapacity >::pop_back(), tbb::interface9::internal::range_vector< T, MaxCapacity >::pop_front(), tbb::interface9::internal::range_vector< T, MaxCapacity >::size(), and tbb::interface9::internal::range_vector< T, MaxCapacity >::split_to_fill().

Here is the call graph for this function:

Member Data Documentation

◆ 

◆ my_max_depth

◆ range_pool_size

template<class Mode >
const unsigned tbb::interface9::internal::dynamic_grainsize_mode< Mode >::range_pool_size = __TBB_RANGE_POOL_CAPACITY
static

Definition at line 375 of file partitioner.h.


The documentation for this struct was generated from the following file:

Copyright © 2005-2020 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.