为什么 C++ 标准中没有并行的“std::accumulate”?

Ant*_*ahl 26 c++ parallel-processing std accumulate c++17

std::accumulate我认为C++ 标准中没有并行版本是令人困惑的。在我看来,并行实现它是微不足道的,例如基于 OpenMP 或 SIMD 指令。std::reduce有人对为什么标准委员会选择引入but not的并行版本有一个很好的解释吗std::accumulate?是因为迭代器类型不同吗?

Nic*_*las 66

他们引入是reduce因为accumulate 不能像编写的那样并行化。

C++ 标准定义了各种函数的预期行为。accumulate定义如下:

acc通过使用初始值初始化累加器来计算其结果init,然后使用acc = std::move(acc) + *ior为 order范围内的acc = binary_op(std::move(acc), *i)每个迭代器修改它。i[first, last)

添加了强调。这两个词使算法变得不可并行。因为这些词是标准的一部分,所以用户accumulate可以依赖“有序”保证。它们可以进行关联操作operator+或非binary_op关联操作,这些操作依赖于操作的顺序。因此,委员会不能在不破坏一堆代码的情况下就删除这些文字。

他们不希望并行版本的accumulate行为与非并行版本有根本不同。因此,reduce在没有“按顺序”保证的情况下引入(并且使用其他有助于使其可并行化的语言)。

  • 也许值得注意的是,即使“binary_op”是不可交换的,只要“binary_op”是关联的,就可以编写 std::accumulate 的并行版本,例如,如果“binary_op”正在进行矩阵乘法。 (7认同)
  • 除非在假设规则的范围内,否则不可并行。例如,编译器仍然可以在“uint32_t”数组上自动向量化“std::accumulate”,因为它是真正关联的,与 FP 加法不同。GCC `-ftree-parallelize-loops=4` 甚至可以并行化它,如果它期望它有利可图的话(https://gcc.gnu.org/wiki/AutoParInGCC)。因此,“std::reduce”的真正好处在于对 FP 数组或 FP 点积求和之类的东西。为了使线程级并行性对于实际的编译器/优化器来说是明确的,而不是像 SIMD 并行性那样必须发明一些东西。 (4认同)