Advanced Topic: Other Kinds of Iteration Spaces

The examples so far have used the class blocked_range<T> to specify ranges. This class is useful in many situations, but it does not fit every situation. You can use Intel® Threading Building Blocks to define your own iteration space objects. The object must specify how it can be split into subspaces by providing two methods and a "splitting constructor". If your class is called R, the methods and constructor could be as follows:

class R {
    // True if range is empty
    bool empty() const;
    // True if range can be split into non-empty subranges
    bool is_divisible() const;
    // Split r into subranges r and *this
    R( R& r, split );
    ...
};

The method empty should return true if the range is empty. The method is_divisible should return true if the range can be split into two non-empty subspaces, and such a split is worth the overhead. The splitting constructor should take two arguments:

The second argument is not used; it serves only to distinguish the constructor from an ordinary copy constructor. The splitting constructor should attempt to split r roughly into two halves, and update r to be the first half, and let constructed object be the second half. The two halves should be non-empty. The parallel algorithm templates call the splitting constructor on r only if r.is_divisible is true.

The iteration space does not have to be linear. Look at tbb/blocked_range2d.h for an example of a range that is two-dimensional. Its splitting constructor attempts to split the range along its longest axis. When used with parallel_for, it causes the loop to be "recursively blocked" in a way that improves cache usage. This nice cache behavior means that using parallel_for over a blocked_range2d<T> can make a loop run faster than the sequential equivalent, even on a single processor.

Code Samples

The directory examples/parallel_for/seismic contains a simple seismic wave simulation based on parallel_for and blocked_range. The directory examples/parallel_for/tachyon contains a more complex example of a ray tracer based on parallel_for and blocked_range2d.