std::experimental::parallel:: transform_reduce
|
定义于头文件
<experimental/numeric>
|
||
|
template
<
class
InputIt,
class
UnaryOp,
class
T,
class
BinaryOp
>
T transform_reduce
(
InputIt first, InputIt last,
|
(1) | (并行性TS) |
|
template
<
class
ExecutionPolicy,
class
InputIt,
class
UnaryOp,
class
T,
class
BinaryOp
>
|
(2) | (并行性TS) |
对范围
[
first
,
last
)
中的每个元素应用
unary_op
,并将结果(可能以未指定的方式重排和聚合)与初始值
init
通过
binary_op
进行归约。
如果 binary_op 不满足结合律或交换律,则该行为是不确定的。
如果
unary_op
或
binary_op
修改了
[
first
,
last
)
范围内的任何元素或使任何迭代器失效,则行为未定义。
目录 |
参数
| first, last | - | 应用算法处理的元素范围 |
| init | - | 广义求和的初始值 |
| policy | - | 执行策略 |
| unary_op | - | 一元 函数对象 ,将应用于输入范围的每个元素。其返回类型必须可作为 binary_op 的输入 |
| binary_op | - | 二元 函数对象 ,将以未指定顺序应用于 unary_op 的结果、其他 binary_op 的结果以及 init |
| 类型要求 | ||
-
InputIt
必须满足
LegacyInputIterator
的要求。
|
||
返回值
init 与 unary_op ( * first ) 、 unary_op ( * ( first + 1 ) ) …… unary_op ( * ( last - 1 ) ) 在 binary_op 上的广义和, 其中广义和 GSUM(op, a 1 , ..., a N ) 定义如下:
- 若 N = 1 , a 1 ,
- 若 N > 1 , op(GSUM(op, b 1 , ..., b K ), GSUM(op, b M , ..., b N )) 其中
-
- b 1 , ..., b N 可以是 a1, ..., aN 的任意排列,且
- 1 < K + 1 = M ≤ N
换句话说, unary_op 的结果可以按任意顺序进行分组和排列。
复杂度
O(last - first) 次对 unary_op 和 binary_op 的各自调用。
异常
- 如果作为算法一部分调用的函数执行抛出异常,
-
-
若
policy为parallel_vector_execution_policy,则调用 std::terminate 。 -
若
policy为sequential_execution_policy或parallel_execution_policy,算法将以包含所有未捕获异常的 exception_list 退出。若仅存在一个未捕获异常,算法可能直接重新抛出该异常而不将其包装在exception_list中。未指明在遇到首个异常后、返回前算法将执行多少工作。 -
若
policy为其他类型,其行为由实现定义。
-
若
-
如果算法无法分配内存(无论是为自身分配还是在处理用户异常时构造
exception_list),将抛出 std::bad_alloc 。
注释
unary_op 不应用于 init 。
如果范围为空,将返回未经修改的 init 。
-
如果
policy是sequential_execution_policy的实例,所有操作将在调用线程中执行。 -
如果
policy是parallel_execution_policy的实例,操作可能在未指定数量的线程中执行,彼此之间以不确定的顺序进行。 -
如果
policy是parallel_vector_execution_policy的实例,执行可能同时并行化和向量化:函数体边界不被遵守,用户代码可能以任意方式重叠和组合(特别地,这意味着用户提供的可调用对象不得通过获取互斥锁来访问共享资源)。
示例
transform_reduce 可用于并行化 std::inner_product :
#include <boost/iterator/zip_iterator.hpp> #include <boost/tuple.hpp> #include <experimental/execution_policy> #include <experimental/numeric> #include <functional> #include <iostream> #include <iterator> #include <vector> int main() { std::vector<double> xvalues(10007, 1.0), yvalues(10007, 1.0); double result = std::experimental::parallel::transform_reduce( std::experimental::parallel::par, boost::iterators::make_zip_iterator( boost::make_tuple(std::begin(xvalues), std::begin(yvalues))), boost::iterators::make_zip_iterator( boost::make_tuple(std::end(xvalues), std::end(yvalues))), [](auto r) { return boost::get<0>(r) * boost::get<1>(r); } 0.0, std::plus<>() ); std::cout << result << '\n'; }
输出:
10007
参见
|
对范围内的元素进行求和或折叠操作
(函数模板) |
|
|
对范围内的元素应用函数,并将结果存储到目标范围
(函数模板) |
|
|
(parallelism TS)
|
类似于
std::accumulate
,但以无序方式执行
(函数模板) |