C++17 / C++1z parallel usage of std::for_each

Viewed 6757

I want to use C++17 parallel capabilities to divide every element of a std::vector by some constant and store the result in another std::vector of same length and (!!) order.

E.g.

{6,9,12} / 3 = {2,3,4}

I have a not compiling example

#include <execution>
#include <algorithm>

template <typename T>
std::vector<T> & divide(std::vector<T> const & in)
{
  std::vector<T> out(in.size(), 0);

  float const divisor = 3;

  std::for_each
  ( std::execution::par_unseq
  , in.begin()
  , in.end()
  , /* divide each element by divisor and put result in out */ );

  return out;
}

How can I get this running, lockless and threadsafe?

2 Answers

You want std::transform for this, not std::for_each. Transofrm takes input and output iterators.

The good thing about std::transform is that it is trivial to distribute to multiple CPU cores, if needed. So:

#include <execution>
#include <algorithm>

template <typename T>
std::vector<T> & divide(std::vector<T> const & in)
{
  std::vector<T> out(in.size(), 0);

  float const divisor = 3;

  std::transform
  ( std::execution::par_unseq
    in.begin(),
    in.end(),
    out.begin(),
    out.end(),
        [divisor](float val) {
            // modifies value in place
            return val / divisor;
        });

  return out;
}

Sidenote: if you are into speed, either enable -ffast-math or multiply with (1 / divisor)

Related