I discovered the std::reduce
algorithm recently and wanted to compare it with std::accumulate
. I found this blog post explaining how std::reduce
can be parallelised using std::execution::par
. However, the blog post notes that parallelisation only works with operations that are "both associative and commutative."
I wanted to test this out. While I originally thought that subtraction failed due to the algorithm being parallelised, I discovered that it seems std::reduce
doesn't give the correct answer for subtraction even when used with std::execution::seq
or just run without an execution policy (which should run the algorithm sequentially).
Running this:
std::vector<int> vec = {5, 4, 3, 2, 1};
auto diff = std::reduce(begin(vec), end(vec), 0, std::minus<>{});
std::cout << diff << "\n";
Gives this output:
-1
Am I doing something wrong? Or does std::reduce
just never work with subtraction?
Yes you can, with a very slight modification to the calculation. You need to leave the first value out of reduce, and subtract the sum of the other elements.
#include <iostream>
#include <execution>
#include <numeric>
#include <vector>
int main()
{
std::vector<int> vec = { 5, 4, 3, 2, 1 };
auto sum_of_rest = std::reduce(std::execution::par, vec.begin() + 1, vec.end());
auto diff = vec.front() - sum_of_rest;
std::cout << diff << "\n";
return 0;
}