Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I use std::transform in place with a parallel execution policy?

If I am not mistaken, I can make std::transform perform in place by using the same range as an input and output iterator. Assume I have some std::vector object vec, then I would write

std::transform(vec.cbegin(),vec.cend(),vec.begin(),unary_op)

using a suitable unary operation unary_op.

Using the C++17 standard, I would like to execute the transform in parallel by sticking an std::execution::par in there as the first argument. This would make the function go from overload (1) to (2) in the cppreference article on std::transform. However the comments to this overload says:

unary_op [...] must not invalidate any iterators, including the end iterators, or modify any elements of the ranges involved. (since C++11)

Does "modify any elements" really mean I cannot use the algorithm in place or is this talking about a different detail that I misinterpreted?

like image 369
geo Avatar asked Oct 06 '19 18:10

geo


1 Answers

I believe that it's talking about a different detail. The unary_op takes an element of the sequence and returns a value. That value is stored (by transform) into the destination sequence.

So this unary_op would be fine:

int times2(int v) { return 2*v; }

but this one would not:

int times2(int &v) { return v*=2; }

But that's not really what you're asking about. You want to know if you can use the unary_op version of transform as a parallel algorithm with the same source and destination range. I don't see why not. transform maps a single element of the source sequence to a single element of the destination sequence. However, if your unary_op isn't really unary, (i.e, it references other elements in the sequence - even if it only reads them, then you will have a data race).

like image 126
Marshall Clow Avatar answered Sep 24 '22 19:09

Marshall Clow