1.. _Advanced_Topic_Other_Kinds_of_Iteration_Spaces: 2 3Advanced Topic: Other Kinds of Iteration Spaces 4=============================================== 5 6 7The examples so far have used the class ``blocked_range<T>`` to specify ranges. 8This class is useful in many situations, but it does not fit every situation. 9You can use |full_name| to define your own iteration space objects. The object 10must specify how it can be split into subspaces by providing a basic splitting 11constructor, an optional proportional splitting constructor, and two predicate 12methods. If your class is called ``R``, the methods and constructors should be 13as follows: 14 15 16:: 17 18 19 class R { 20 // True if range is empty 21 bool empty() const; 22 // True if range can be split into non-empty subranges 23 bool is_divisible() const; 24 // Splits r into subranges r and *this 25 R( R& r, split ); 26 // (optional) Splits r into subranges r and *this in proportion p 27 R( R& r, proportional_split p ); 28 ... 29 }; 30 31 32 33 34The method ``empty`` should return true if the range is empty. The 35method ``is_divisible`` should return true if the range can be split 36into two non-empty subspaces, and such a split is worth the overhead. 37The basic splitting constructor should take two arguments: 38 39 40- The first of type ``R`` 41 42 43- The second of type oneapi::tbb::split 44 45 46The second argument is not used; it serves only to distinguish the 47constructor from an ordinary copy constructor. The basic splitting 48constructor should attempt to split ``r`` roughly into two halves, and 49update ``r`` to be the first half, and set the constructed object as the 50second half. 51 52 53Unlike the basic splitting constructor, the proportional splitting 54constructor is optional and takes the second argument of type 55``oneapi::tbb::proportional_split``. The type has methods ``left`` and ``right`` 56that return the values of the proportion. These values should be used to 57split ``r`` accordingly, so that the updated ``r`` corresponds to the 58left part of the proportion, and the constructed object corresponds to 59the right part. 60 61 62Both splitting constructors should guarantee that the updated ``r`` part 63and the constructed object are not empty. The parallel algorithm 64templates call the splitting constructors on ``r`` only if 65``r.is_divisible`` is true. 66 67 68The iteration space does not have to be linear. Look at 69``oneapi/tbb/blocked_range2d.h`` for an example of a range that is 70two-dimensional. Its splitting constructor attempts to split the range 71along its longest axis. When used with ``parallel_for``, it causes the 72loop to be "recursively blocked" in a way that improves cache usage. 73This nice cache behavior means that using ``parallel_for`` over a 74``blocked_range2d<T>`` can make a loop run faster than the sequential 75equivalent, even on a single processor. 76