BRE12
blocked_range.h
1 /*
2  Copyright 2005-2016 Intel Corporation. All Rights Reserved.
3 
4  This file is part of Threading Building Blocks. Threading Building Blocks is free software;
5  you can redistribute it and/or modify it under the terms of the GNU General Public License
6  version 2 as published by the Free Software Foundation. Threading Building Blocks is
7  distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
8  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9  See the GNU General Public License for more details. You should have received a copy of
10  the GNU General Public License along with Threading Building Blocks; if not, write to the
11  Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
12 
13  As a special exception, you may use this file as part of a free software library without
14  restriction. Specifically, if other files instantiate templates or use macros or inline
15  functions from this file, or you compile this file and link it with other files to produce
16  an executable, this file does not by itself cause the resulting executable to be covered
17  by the GNU General Public License. This exception does not however invalidate any other
18  reasons why the executable file might be covered by the GNU General Public License.
19 */
20 
21 #ifndef __TBB_blocked_range_H
22 #define __TBB_blocked_range_H
23 
24 #include "tbb_stddef.h"
25 
26 namespace tbb {
27 
37 
39 template<typename Value>
41 public:
43 
45  typedef Value const_iterator;
46 
48  typedef std::size_t size_type;
49 
51 
52  blocked_range() : my_end(), my_begin() {}
53 
55  blocked_range( Value begin_, Value end_, size_type grainsize_=1 ) :
56  my_end(end_), my_begin(begin_), my_grainsize(grainsize_)
57  {
58  __TBB_ASSERT( my_grainsize>0, "grainsize must be positive" );
59  }
60 
62  const_iterator begin() const {return my_begin;}
63 
65  const_iterator end() const {return my_end;}
66 
68 
69  size_type size() const {
70  __TBB_ASSERT( !(end()<begin()), "size() unspecified if end()<begin()" );
71  return size_type(my_end-my_begin);
72  }
73 
75  size_type grainsize() const {return my_grainsize;}
76 
77  //------------------------------------------------------------------------
78  // Methods that implement Range concept
79  //------------------------------------------------------------------------
80 
82  bool empty() const {return !(my_begin<my_end);}
83 
85 
86  bool is_divisible() const {return my_grainsize<size();}
87 
89 
92  my_end(r.my_end),
93  my_begin(do_split(r, split())),
94  my_grainsize(r.my_grainsize)
95  {
96  // only comparison 'less than' is required from values of blocked_range objects
97  __TBB_ASSERT( !(my_begin < r.my_end) && !(r.my_end < my_begin), "blocked_range has been split incorrectly" );
98  }
99 
100 #if __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES
101  static const bool is_splittable_in_proportion = true;
103 
105 
107  blocked_range( blocked_range& r, proportional_split& proportion ) :
108  my_end(r.my_end),
109  my_begin(do_split(r, proportion)),
110  my_grainsize(r.my_grainsize)
111  {
112  // only comparison 'less than' is required from values of blocked_range objects
113  __TBB_ASSERT( !(my_begin < r.my_end) && !(r.my_end < my_begin), "blocked_range has been split incorrectly" );
114  }
115 #endif /* __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES */
116 
117 private:
119  Value my_end;
120  Value my_begin;
121  size_type my_grainsize;
122 
124 
125  static Value do_split( blocked_range& r, split )
126  {
127  __TBB_ASSERT( r.is_divisible(), "cannot split blocked_range that is not divisible" );
128  Value middle = r.my_begin + (r.my_end - r.my_begin) / 2u;
129  r.my_end = middle;
130  return middle;
131  }
132 
133 #if __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES
134  static Value do_split( blocked_range& r, proportional_split& proportion )
135  {
136  __TBB_ASSERT( r.is_divisible(), "cannot split blocked_range that is not divisible" );
137 
138  // usage of 32-bit floating point arithmetic is not enough to handle ranges of
139  // more than 2^24 iterations accurately. However, even on ranges with 2^64
140  // iterations the computational error approximately equals to 0.000001% which
141  // makes small impact on uniform distribution of such range's iterations (assuming
142  // all iterations take equal time to complete). See 'test_partitioner_whitebox'
143  // for implementation of an exact split algorithm
144  size_type right_part = size_type(float(r.size()) * float(proportion.right())
145  / float(proportion.left() + proportion.right()) + 0.5f);
146  return r.my_end = Value(r.my_end - right_part);
147  }
148 #endif /* __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES */
149 
150  template<typename RowValue, typename ColValue>
151  friend class blocked_range2d;
152 
153  template<typename RowValue, typename ColValue, typename PageValue>
154  friend class blocked_range3d;
155 };
156 
157 } // namespace tbb
158 
159 #endif /* __TBB_blocked_range_H */
A 3-dimensional range that models the Range concept.
Definition: blocked_range3d.h:32
Value const_iterator
Type of a value.
Definition: blocked_range.h:45
const_iterator begin() const
Beginning of range.
Definition: blocked_range.h:62
std::size_t size_type
Type for size of a range.
Definition: blocked_range.h:48
bool empty() const
True if range is empty.
Definition: blocked_range.h:82
A range over which to iterate.
Definition: blocked_range.h:40
const_iterator end() const
One past last value in range.
Definition: blocked_range.h:65
blocked_range(blocked_range &r, proportional_split &proportion)
Split range.
Definition: blocked_range.h:107
size_type grainsize() const
The grain size for this range.
Definition: blocked_range.h:75
size_type size() const
Size of the range.
Definition: blocked_range.h:69
blocked_range()
Construct range with default-constructed values for begin and end.
Definition: blocked_range.h:52
blocked_range(Value begin_, Value end_, size_type grainsize_=1)
Construct range over half-open interval [begin,end), with the given grainsize.
Definition: blocked_range.h:55
A 2-dimensional range that models the Range concept.
Definition: blocked_range2d.h:32
bool is_divisible() const
True if range is divisible.
Definition: blocked_range.h:86
The namespace tbb contains all components of the library.
Definition: parallel_for.h:44
blocked_range(blocked_range &r, split)
Split range.
Definition: blocked_range.h:91
static const bool is_splittable_in_proportion
Static field to support proportional split.
Definition: blocked_range.h:102