Use of r-Values for Reduction

Use of r-Values for Reduction#

The functional form of parallel_reduce supports rvalue references in both the reduction function and the combine function. This allows efficient use of move operations when accumulated results are expensive to copy.

The example below merges a collection of std::set objects into a single set. Because the accumulator is passed as an rvalue reference, the algorithm can transfer nodes between sets without copying or moving the underlying data.

// C++17
#include <oneapi/tbb/parallel_reduce.h>
#include <oneapi/tbb/blocked_range.h>
#include <vector>
#include <set>

int main() {
    std::vector<std::set<int>> sets;

    oneapi::tbb::parallel_reduce(oneapi::tbb::blocked_range<size_t>(0, sets.size()),
                                    std::set<int>{}, // identity element - empty set
                                    [&](const oneapi::tbb::blocked_range<size_t>& range, std::set<int>&& value) {
                                        for (size_t i = range.begin(); i < range.end(); ++i) {
                                            // Having value as a non-const rvalue reference enables efficient
                                            // transfer of nodes from sets[i] without copying or moving the elements
                                            value.merge(std::move(sets[i]));
                                        }
                                        return value;
                                    },
                                    [&](std::set<int>&& x, std::set<int>&& y) {
                                        x.merge(std::move(y));
                                        return std::move(x);
                                    }
                                    );
}

See also