17 #ifndef __TBB_partitioner_H    18 #define __TBB_partitioner_H    20 #define __TBB_partitioner_H_include_area    23 #ifndef __TBB_INITIAL_CHUNKS    25 #define __TBB_INITIAL_CHUNKS 2    27 #ifndef __TBB_RANGE_POOL_CAPACITY    29 #define __TBB_RANGE_POOL_CAPACITY 8    31 #ifndef __TBB_INIT_DEPTH    33 #define __TBB_INIT_DEPTH 5    35 #ifndef __TBB_DEMAND_DEPTH_ADD    37 #define __TBB_DEMAND_DEPTH_ADD 1    39 #ifndef __TBB_STATIC_THRESHOLD    41 #define __TBB_STATIC_THRESHOLD 40000    44 #define __TBB_NONUNIFORM_TASK_CREATION 1    45 #ifdef __TBB_time_stamp    46 #define __TBB_USE_MACHINE_TIME_STAMPS 1    47 #define __TBB_task_duration() __TBB_STATIC_THRESHOLD    48 #endif // __TBB_machine_time_stamp    49 #endif // __TBB_DEFINE_MIC    57 #if defined(_MSC_VER) && !defined(__INTEL_COMPILER)    59     #pragma warning (push)    60     #pragma warning (disable: 4244)    65 class auto_partitioner;
    66 class simple_partitioner;
    67 class static_partitioner;
    68 class affinity_partitioner;
    70 namespace interface9 {
    72         class affinity_partition_type;
   109 template<
typename Range, 
typename Body, 
typename Partitioner> 
class start_scan;
   114 namespace interface9 {
   115 template<
typename Range, 
typename Body, 
typename Partitioner> 
class start_for;
   119 namespace interface9 {
   123 template<
typename Range, 
typename Body, 
typename Partitioner> 
class start_for;
   124 template<
typename Range, 
typename Body, 
typename Partitioner> 
class start_reduce;
   125 template<
typename Range, 
typename Body, 
typename Partitioner> 
class start_deterministic_reduce;
   134         tbb::atomic<bool> &flag = static_cast<flag_task*>(t.
parent())->my_child_stolen;
   135 #if TBB_USE_THREADING_TOOLS   137         flag.fetch_and_store<
release>(
true);
   140 #endif //TBB_USE_THREADING_TOOLS   143         return static_cast<flag_task*>(t.
parent())->my_child_stolen;
   153 template <
typename T, depth_t MaxCapacity>
   165         new( static_cast<void *>(my_pool.begin()) ) T(elem);
   168         while( !empty() ) pop_back();
   170     bool empty()
 const { 
return my_size == 0; }
   175         while( my_size < MaxCapacity && is_divisible(max_depth) ) {
   177             my_head = (my_head + 1) % MaxCapacity;
   178             new(my_pool.begin()+my_head) T(my_pool.begin()[prev]); 
   179             my_pool.begin()[prev].~T(); 
   180             new(my_pool.begin()+prev) T(my_pool.begin()[my_head], 
split()); 
   181             my_depth[my_head] = ++my_depth[prev];
   186         __TBB_ASSERT(my_size > 0, 
"range_vector::pop_back() with empty size");
   187         my_pool.begin()[my_head].~T();
   189         my_head = (my_head + MaxCapacity - 1) % MaxCapacity;
   192         __TBB_ASSERT(my_size > 0, 
"range_vector::pop_front() with empty size");
   193         my_pool.begin()[my_tail].~T();
   195         my_tail = (my_tail + 1) % MaxCapacity;
   198         __TBB_ASSERT(my_size > 0, 
"range_vector::back() with empty size");
   199         return my_pool.begin()[my_head];
   202         __TBB_ASSERT(my_size > 0, 
"range_vector::front() with empty size");
   203         return my_pool.begin()[my_tail];
   207         __TBB_ASSERT(my_size > 0, 
"range_vector::front_depth() with empty size");
   208         return my_depth[my_tail];
   211         __TBB_ASSERT(my_size > 0, 
"range_vector::back_depth() with empty size");
   212         return my_depth[my_head];
   215         return back_depth() < max_depth && back().is_divisible();
   220 template <
typename Partition>
   232     Partition& 
self() { 
return *static_cast<Partition*>(
this); } 
   234     template<
typename StartType, 
typename Range>
   236         start.run_body( range ); 
   239     template<
typename StartType, 
typename Range>
   240     void execute(StartType &start, Range &range) {
   248         if ( range.is_divisible() ) {
   249             if ( 
self().is_divisible() ) {
   251                     typename Partition::split_type split_obj = 
self().
template get_split<Range>();
   252                     start.offer_work( split_obj );
   253                 } 
while ( range.is_divisible() && 
self().is_divisible() );
   256         self().work_balance(start, range);
   261 template <
typename Partition>
   269     static const unsigned factor = 1;
   283 template <
typename Range, 
typename = 
void>
   287 template <
typename Range>
   290 #if __TBB_NONUNIFORM_TASK_CREATION   291         size_t right = (n + 2) / 3;
   293         size_t right = n / 2;
   295         size_t left = n - right;
   301 template <
typename Partition>
   310 #if __TBB_ENABLE_RANGE_FEEDBACK   311         size_t portion = size_t(
float(src.
my_divisor) * 
float(split_obj.
right())
   312                                 / 
float(split_obj.
left() + split_obj.
right()) + 0.5f);
   314         size_t portion = split_obj.
right() * my_partition::factor;
   316         portion = (portion + my_partition::factor/2) & (0ul - my_partition::factor);
   317 #if __TBB_ENABLE_RANGE_FEEDBACK   320             portion = my_partition::factor;
   322             portion = src.
my_divisor - my_partition::factor;
   328         return self().my_divisor > my_partition::factor;
   330     template <
typename Range>
   341     return size_t(current_index);
   345 template <
typename Partition>
   351                              my_max_affinity(self().my_divisor) {}
   353         , my_head((src.my_head + src.my_divisor) % src.my_max_affinity), my_max_affinity(src.my_max_affinity) {}
   355         , my_head((src.my_head + src.my_divisor) % src.my_max_affinity), my_max_affinity(src.my_max_affinity) {}
   357         if( 
self().my_divisor )
   366 #ifdef __TBB_USE_MACHINE_TIME_STAMPS   377 #ifdef __TBB_USE_MACHINE_TIME_STAMPS
   384 #ifdef __TBB_USE_MACHINE_TIME_STAMPS
   388         , my_max_depth(
p.my_max_depth) {}
   391 #ifdef __TBB_USE_MACHINE_TIME_STAMPS
   395         , my_max_depth(
p.my_max_depth) {}
   397         if( !(
self().my_divisor / Mode::my_partition::factor) ) { 
   398             self().my_divisor = 1; 
   400 #if __TBB_USE_OPTIONAL_RTTI   408                 if( !my_max_depth ) my_max_depth++;
   418         my_max_depth -= base;
   420     template<
typename StartType, 
typename Range>
   422         if( !range.is_divisible() || !
self().max_depth() ) {
   423             start.run_body( range ); 
   429                 if( 
self().check_for_demand( start ) ) {
   430                     if( range_pool.
size() > 1 ) {
   438                 start.run_body( range_pool.
back() );
   440             } 
while( !range_pool.
empty() && !start.is_cancelled() );
   444         if( pass == my_delay ) {
   445             if( 
self().my_divisor > 1 ) 
   447             else if( 
self().my_divisor && my_max_depth ) { 
   448                 self().my_divisor = 0; 
   455         } 
else if( 
begin == my_delay ) {
   456 #ifndef __TBB_USE_MACHINE_TIME_STAMPS   461         } 
else if( run == my_delay ) {
   469 #endif // __TBB_USE_MACHINE_TIME_STAMPS   484         if( my_divisor > 1 ) 
return true;
   485         if( my_divisor && my_max_depth ) { 
   505     template<
typename StartType, 
typename Range>
   506     void execute(StartType &start, Range &range) {
   507         split_type split_obj = 
split(); 
   508         while( range.is_divisible() )
   509             start.offer_work( split_obj );
   510         start.run_body( range );
   526     static const unsigned factor_power = 4; 
   529     static const unsigned factor = 1 << factor_power; 
   533         __TBB_ASSERT( (factor&(factor-1))==0, 
"factor must be power of two" );
   536         my_max_depth = factor_power + 1;
   541         , my_array(
p.my_array) {}
   544         , my_array(
p.my_array) {}
   547             if( !my_array[my_head] )
   556             my_array[my_head] = 
id;
   563     static const size_t VICTIM_CHUNKS = 4;
   567             num_chunks = VICTIM_CHUNKS;
   568         return num_chunks==1;
   606     typedef interface9::internal::simple_partition_type::split_type 
split_type;
   628     typedef interface9::internal::auto_partition_type::split_type 
split_type;
   671 #if defined(_MSC_VER) && !defined(__INTEL_COMPILER)   672     #pragma warning (pop)   673 #endif // warning 4244 is back   674 #undef __TBB_INITIAL_CHUNKS   675 #undef __TBB_RANGE_POOL_CAPACITY   676 #undef __TBB_INIT_DEPTH   679 #undef __TBB_partitioner_H_include_area 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
 
Join task node that contains shared flag for stealing feedback.
 
void work_balance(StartType &start, Range &range)
 
bool should_execute_range(const task &)
 
void execute(StartType &start, Range &range)
simplified algorithm
 
auto_partition_type(const auto_partitioner &)
 
simple_partition_type(const simple_partitioner &)
 
old_auto_partition_type(const auto_partitioner &)
 
affinity_partition_type(tbb::internal::affinity_partitioner_base_v3 &ap)
 
bool check_being_stolen(task &)
 
old_auto_partition_type(const affinity_partitioner &)
 
static void mark_task_stolen(task &t)
 
static size_t get_initial_partition_head()
 
static_partition_type(static_partition_type &p, split)
 
void work_balance(StartType &start, Range &range)
 
tbb::aligned_space< T, MaxCapacity > my_pool
 
Task type used to split the work of parallel_reduce.
 
static proportional_split get_split(size_t n)
 
void align_depth(depth_t base)
 
Base class for user-defined tasks.
 
size_t __TBB_EXPORTED_FUNC get_initial_auto_partitioner_divisor()
 
bool should_execute_range(const task &t)
 
linear_affinity_mode(linear_affinity_mode &src, const proportional_split &split_obj)
 
~affinity_partitioner_base_v3()
Deallocates my_array.
 
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 set_affinity(task &t)
 
size_t my_size
Number of elements in my_array.
 
Task type used to split the work of parallel_deterministic_reduce.
 
#define __TBB_INITIAL_CHUNKS
 
Provides default linear indexing of partitioner's sequence.
 
proportional_split split_type
 
void note_affinity(task::affinity_id)
 
adaptive_mode(adaptive_mode &src, split)
 
proportional_split split_type
 
interface9::internal::affinity_partition_type task_partition_type
 
#define __TBB_time_stamp()
 
auto_partition_type(auto_partition_type &src, split)
 
partition_type(const partition_type &, split)
 
range_vector(const T &elem)
initialize via first range in pool
 
dynamic_grainsize_mode(dynamic_grainsize_mode &p, split)
 
bool decide_whether_to_delay()
 
Type enables transmission of splitting proportion from partitioners to range objects.
 
affinity_id * my_array
Array that remembers affinities of tree positions to affinity_id.
 
interface9::internal::old_auto_partition_type partition_type
 
void __TBB_EXPORTED_METHOD resize(unsigned factor)
Resize my_array.
 
bool check_for_demand(task &)
 
static proportional_split get_split(size_t)
 
proportional_mode(proportional_mode &src, const proportional_split &split_obj)
 
interface9::internal::simple_partition_type::split_type split_type
 
A helper class to create a proportional_split object for a given type of Range.
 
Range pool stores ranges of type T in a circular buffer with MaxCapacity.
 
static_partition_type(const static_partitioner &)
 
void set_affinity(task &t)
 
proportional_mode(proportional_mode &src, split)
 
size_t do_split(adaptive_mode &src, split)
 
static_partition_type(static_partition_type &p, const proportional_split &split_obj)
 
void set_affinity(affinity_id id)
Set affinity for this task.
 
size_t do_split(proportional_mode &src, const proportional_split &split_obj)
 
void set_affinity(task &)
 
Provides proportional splitting strategy for partition objects.
 
bool check_being_stolen(task &t)
 
Provides default splitting strategy for partition objects.
 
void const char const char int ITT_FORMAT __itt_group_sync p
 
#define __TBB_EXPORTED_FUNC
 
interface9::internal::old_auto_partition_type partition_type
 
depth_t front_depth()
similarly to front(), returns depth of the first range in the pool
 
partition_type(const simple_partitioner &)
 
affinity_partitioner_base_v3()
Zeros the fields.
 
Initial task to split the work.
 
proportional_split get_split()
 
void spawn_or_delay(bool, task &b)
 
task * execute() __TBB_override
Should be overridden by derived classes.
 
interface9::internal::simple_partition_type task_partition_type
 
static bool is_peer_stolen(task &t)
 
affinity_partition_type(affinity_partition_type &p, const proportional_split &split_obj)
 
unsigned short affinity_id
An id as used for specifying affinity.
 
Dummy type that distinguishes splitting constructor from copy constructor.
 
interface9::internal::static_partition_type::split_type split_type
 
tbb::internal::affinity_id * my_array
 
Base class for types that should not be copied or assigned.
 
linear_affinity_mode(linear_affinity_mode &src, split)
 
void note_affinity(task::affinity_id id)
 
static const int not_initialized
 
void align_depth(depth_t)
 
interface9::internal::old_auto_partition_type partition_type
 
bool is_divisible(depth_t max_depth)
 
int ref_count() const
The internal reference count.
 
tbb::atomic< bool > my_child_stolen
 
Enables one or the other code branches.
 
bool check_for_demand(task &t)
 
simple_partition_type(const simple_partition_type &, split)
 
Backward-compatible partition for auto and affinity partition objects.
 
bool is_stolen_task() const
True if task was stolen from the task pool of another thread.
 
void set_affinity(task &)
 
#define __TBB_EXPORTED_METHOD
 
Provides backward-compatible methods for partition objects without affinity.
 
void execute(StartType &start, Range &range)
 
task * continue_after_execute_range()
 
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
 
dynamic_grainsize_mode(dynamic_grainsize_mode &p, const proportional_split &split_obj)
 
Task type used in parallel_for.
 
int current_thread_index()
Returns the index, aka slot number, of the calling thread in its current arena.
 
void split_to_fill(depth_t max_depth)
 
task * parent() const
task on whose behalf this task is working, or NULL if this is a root.
 
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 ITT_FORMAT lu const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle __itt_metadata_type type
 
interface9::internal::auto_partition_type::split_type split_type
 
#define __TBB_DEMAND_DEPTH_ADD
 
old_auto_partition_type(old_auto_partition_type &pt, split)
 
affinity_partition_type(affinity_partition_type &p, split)
 
Defines entry point for affinity partitioner into TBB run-time library.
 
interface9::internal::auto_partition_type task_partition_type
 
Identifiers declared inside namespace internal should never be used directly by client code.
 
#define __TBB_RANGE_POOL_CAPACITY
 
static const unsigned factor
 
internal::affinity_id affinity_id
An id as used for specifying affinity.
 
interface9::internal::static_partition_type task_partition_type
 
interface9::internal::affinity_partition_type::split_type split_type
 
bool check_for_demand(task &t)
 
void note_affinity(task::affinity_id)