std::experimental::parallel::reduce

来自cppreference.com
在标头 <experimental/numeric> 定义
template<class InputIt >

typenamestd::iterator_traits<InputIt>::value_type reduce(

    InputIt first, InputIt last );
(1) (并行 TS)
template<class ExecutionPolicy, class InputIterator >

typenamestd::iterator_traits<InputIt>::value_type reduce(

    ExecutionPolicy&& policy, InputIt first, InputIt last );
(2) (并行 TS)
template<class InputIt, class T >
T reduce( InputIt first, InputIt last, T init );
(3) (并行 TS)
template<class ExecutionPolicy, class InputIt, class T >
T reduce( ExecutionPolicy&& policy, InputIt first, InputIt last, T init );
(4) (并行 TS)
template<class InputIt, class T, class BinaryOp >
T reduce( InputIt first, InputIt last, T init, BinaryOp binary_op );
(5) (并行 TS)
template<class ExecutionPolicy, class InputIt, class T, class BinaryOp >

T reduce( ExecutionPolicy&& policy,

          InputIt first, InputIt last, T init, BinaryOp binary_op );
(6) (并行 TS)
1)reduce(first, last, typenamestd::iterator_traits<InputIt>::value_type{}) 相同。
3)reduce(first, last, init, std::plus<>()) 相同。
5) 归约范围 [firstlast),可能以未指明的方式,在 binary_op 上同初值 init 一起进行排列和聚合。
2,4,6)(1,3,5) 相同,但根据 policy 执行。

如果 binary_op 不可结合或不可传递,则其行为不确定。

如果 binary_op 修改了任何元素或使 [firstlast) 中的任何迭代器失效,则其行为未定义。

目录

[编辑]参数

first, last - 要应用算法的元素范围
init - 广义和的初值
policy - 执行策略
binary_op - 二元函数对象,将以未指定顺序应用于输入迭代器的解引用结果,其他 binary_op 的结果和 init
类型要求
-
InputIt 必须满足老式输入迭代器(LegacyInputIterator)

[编辑]返回值

init*first, *(first +1), ... *(last -1)binary_op 上的广义和。

其中广义和 GSUM(op, a1, ..., aN) 定义如下:

  • 如果 N=1,则 a1
  • 如果 N > 1,则 op(GSUM(op, b1, ..., bK), GSUM(op, bM, ..., bN)) 其中
  • b1, ..., bN 可能是 a1, ..., aN 的任意排列,且
  • 1 < K+1 = M ≤ N

换言之,范围中的各元素可以任意顺序分组和重排。

[编辑]复杂度

O(last - first) 次运用 binary_op

[编辑]异常

  • 如果作为算法一部分而调用的函数执行抛出了异常,
  • 如果 policyparallel_vector_execution_policy,则调用 std::terminate
  • 如果 policysequential_execution_policyparallel_execution_policy,则算法以抛出包含所有未捕获异常的 exception_list 而退出。如果只有一个未捕获异常,则算法可能重新抛出它而不将之包装到 exception_list 中。未指明算法在发生第一个异常后和返回前会做多少工作。
  • 如果 policy 是某个其他类型,则其行为由实现定义。
  • 如果算法分配内存失败(为其自身,或在处理用户异常时用于构造 exception_list),则抛出 std::bad_alloc

[编辑]注解

如果范围为空,则返回未修改的 init

  • 如果 policysequential_execution_policy 的实例,则所有操作在调用方线程中实施。
  • 如果 policyparallel_execution_policy 的实例,则可以在未指明数量的线程中实施操作,互相之间顺序不确定。
  • 如果 policyparallel_vector_execution_policy 的实例,则其执行可以同时并行化和向量化:不遵循函数体边界,且用户代码可能发生重叠并以任意方式合并(尤其是,这蕴含了用户提供的 Callable 不能为访问共享资源获取互斥体)。

[编辑]示例

reduce 是 std::accumulate 的无顺序版本:

#include <chrono>#include <experimental/execution_policy>#include <experimental/numeric>#include <iostream>#include <numeric>#include <vector>   int main(){std::vector<double> v(10'000'007, 0.5);   {auto t1 =std::chrono::high_resolution_clock::now();double result =std::accumulate(v.begin(), v.end(), 0.0);auto t2 =std::chrono::high_resolution_clock::now();std::chrono::duration<double, std::milli> ms = t2 - t1;std::cout<<std::fixed<<"std::accumulate result "<< result <<" took "<< ms.count()<<" ms\n";}   {auto t1 =std::chrono::high_resolution_clock::now();double result = std::experimental::parallel::reduce(std::experimental::parallel::par, v.begin(), v.end());auto t2 =std::chrono::high_resolution_clock::now();std::chrono::duration<double, std::milli> ms = t2 - t1;std::cout<<"parallel::reduce result "<< result <<" took "<< ms.count()<<" ms\n";}}

可能的输出:

std::accumulate result 5000003.50000 took 12.7365 ms parallel::reduce result 5000003.50000 took 5.06423 ms

[编辑]参阅

求和或折叠范围中元素
(函数模板)[编辑]
应用函数到元素范围,并在目标范围存储结果
(函数模板)[编辑]
(并行 TS)
应用函数对象,然后进行不按顺序的规约
(函数模板)[编辑]
close