c++ - 使用参数 vector 并行调用元素 vector 的成员函数

标签 c++ c++17 c++20 stl-algorithm

鉴于这段代码:

struct T
{
  void f(int const);
};

void f(std::vector<T> &u, std::vector<int> const &v)
{
  for (std::size_t i = 0; i < u.size(); ++i)
    u[i].f(v[i]);
}

是否有一种标准方法可以并行化 void f(std::vector<T> &u, std::vector<int> const &v) 的主体?

这碰巧起作用了( https://godbolt.org/z/gRv9Ze ):

void f(std::vector<T> &u, std::vector<int> const &v)
{
  auto const indices = std::views::iota(0u, u.size()) | std::views::common;

  std::for_each(std::execution::par_unseq, std::begin(indices), std::end(indices),
                [&](std::size_t const i) { u[i].f(v[i]); });
}

但据报道依赖这种行为是错误的(参见此 bug report 还有这个answer )。事实上,这不是并行运行的( https://godbolt.org/z/MPGdHF ):

void f(std::vector<T> &u, std::vector<int> const &v)
{
  std::ranges::iota_view<std::size_t, std::size_t> const indices(0u, u.size());

  std::for_each(std::execution::par_unseq, std::begin(indices), std::end(indices),
                [&](std::size_t const i) { u[i].f(v[i]); });
}

我非常确定应该有一种标准方法来使类似的函数并行运行。我可能错过了一个明显的 算法,但是std::transform在这里似乎不合适,其他的更不合适。

最佳答案

留在 std 中,最好的选择是 std::transform ,其输出迭代器会忽略给它的内容

struct unit_iterator {
    using difference_type = std::ptrdiff_t;
    using value_type = std::tuple<>;
    using pointer = std::tuple<> *;
    using const_pointer = const std::tuple<> *;
    using reference = std::tuple<> &;
    using const reference = const std::tuple<> &;
    using iterator_category = std::random_access_iterator_tag;

    reference operator*() { return value; }
    const_reference operator*() const { return value; }
    reference operator[](difference_type) { return value; }
    const_reference operator[](difference_type) const { return value; }
    pointer operator->() { return &value; }
    const_pointer operator->() const { return &value; }

    unit_iterator& operator++() { return *this; }
    unit_iterator operator++(int) { return *this; }
    unit_iterator& operator+=(difference_type) { return *this; }
    unit_iterator operator+(difference_type) const { return *this; }

    unit_iterator& operator--() { return *this; }
    unit_iterator operator--(int) { return *this; }
    unit_iterator& operator-=(difference_type) { return *this; }
    unit_iterator operator-(difference_type) const { return *this; }

    difference_type operator-(unit_iterator) const { return 0; }

    bool operator==(unit_iterator) const { return true; }
    bool operator!=(unit_iterator) const { return false; }
    bool operator<(unit_iterator) const { return false; }
    bool operator<=(unit_iterator) const { return true; }
    bool operator>(unit_iterator) const { return false; }
    bool operator>=(unit_iterator) const { return true; }
private:
    static value_type value;
};


void f(std::vector<T> &u, std::vector<int> const &v)
{
  std::transform(std::execution::par_unseq, begin(u), end(u), begin(v), unit_iterator{},
                 [](T & u, int v) { u.f(v); return std::tuple<>{}; });
}

关于c++ - 使用参数 vector 并行调用元素 vector 的成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62276252/

相关文章:

C++ 使用 Windows 命名管道

c++ - 有没有办法从整数获取模板类型?

c++ - 我是否需要同步对 std::sort 中使用 std::execution::par 调用的元素的读取?

c++ - `co_yield` 能否在协程恢复时从调用方返回一个值?

c++ - C++20 标准对使用子对象作为模板非类型参数有什么看法?

c++ - 将 OpenGL 与 Eigen 一起用于存储顶点数据和 glVertexAttribPointer

c++ - C++ 函数系统(命令)的输出在 Linux 终端中不显示颜色

c++ - C++ 的多个源文件

c++ - 检查变量是否使用 is_signed 签名

c++ - 概念-如何限制积分模板值