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