std::experimental::parallel:: reduce
|
ヘッダーで定義
<experimental/numeric>
|
||
|
template
<
class
InputIt
>
typename
std::
iterator_traits
<
InputIt
>
::
value_type
reduce
(
|
(1) | (parallelism TS) |
|
template
<
class
ExecutionPolicy,
class
InputIterator
>
typename
std::
iterator_traits
<
InputIt
>
::
value_type
reduce
(
|
(2) | (parallelism TS) |
|
template
<
class
InputIt,
class
T
>
T reduce ( InputIt first, InputIt last, T init ) ; |
(3) | (parallelism TS) |
|
template
<
class
ExecutionPolicy,
class
InputIt,
class
T
>
T reduce ( ExecutionPolicy && policy, InputIt first, InputIt last, T init ) ; |
(4) | (parallelism TS) |
|
template
<
class
InputIt,
class
T,
class
BinaryOp
>
T reduce ( InputIt first, InputIt last, T init, BinaryOp binary_op ) ; |
(5) | (parallelism TS) |
|
template
<
class
ExecutionPolicy,
class
InputIt,
class
T,
class
BinaryOp
>
T reduce
(
ExecutionPolicy
&&
policy,
|
(6) | (parallelism TS) |
[
first
,
last
)
を、指定されない方法で並べ替えおよび集約された可能性のある状態で、初期値
init
と共に
binary_op
に対して縮約します。
binary_op が結合的または可換的でない場合、動作は非決定的となります。
binary_op
が任意の要素を変更するか、
[
first
,
last
)
内の任意のイテレータを無効化する場合、動作は未定義です。
目次 |
パラメータ
| first, last | - | アルゴリズムを適用する要素の範囲 |
| init | - | 一般化された合計の初期値 |
| policy | - | 実行ポリシー |
| binary_op | - | 二項 FunctionObject で、入力イテレータのデリファレンス結果、他の binary_op の結果、および init に対して未指定の順序で適用される |
| 型要件 | ||
-
InputIt
は
LegacyInputIterator
の要件を満たさなければならない。
|
||
戻り値
init と * first 、 * ( first + 1 ) 、... * ( last - 1 ) の一般化された総和を binary_op で計算します。
ここで一般化された合計 GSUM(op, a 1 , ..., a N ) は以下のように定義されます:
- if N=1 , a 1
- if N > 1 , op(GSUM(op, b 1 , ..., b K ), GSUM(op, b M , ..., b N )) where
-
- b 1 , ..., b N は a1, ..., aN の任意の順列であり、
- 1 < K+1 = M ≤ N
言い換えれば、範囲の要素は任意の順序でグループ化および再配置される可能性があります。
計算量
O(last - first) 回の binary_op の適用。
例外
- アルゴリズムの一部として呼び出された関数の実行が例外をスローした場合、
-
-
policyがparallel_vector_execution_policyの場合、 std::terminate が呼び出されます。 -
policyがsequential_execution_policyまたはparallel_execution_policyの場合、このアルゴリズムは未捕捉の例外をすべて含む exception_list で終了します。未捕捉の例外が1つだけの場合、アルゴリズムはexception_listでラップせずにその例外を再スローすることがあります。最初の例外が発生した後にアルゴリズムが返されるまでにどの程度の処理が実行されるかは未規定です。 -
policyがその他の型の場合、動作は実装定義です。
-
-
アルゴリズムがメモリの確保に失敗した場合(自身のため、またはユーザー例外を処理する際に
exception_listを構築するため)、 std::bad_alloc がスローされます。
注記
範囲が空の場合、 init が変更されずに返されます。
-
policyがsequential_execution_policyのインスタンスの場合、すべての操作は呼び出し元スレッドで実行されます。 -
policyがparallel_execution_policyのインスタンスの場合、操作は未指定数のスレッドで実行され、互いに非決定的な順序で実行される可能性があります。 -
policyがparallel_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
関連項目
|
要素の範囲を合計または畳み込む
(関数テンプレート) |
|
|
要素の範囲に関数を適用し、結果を宛先範囲に格納する
(関数テンプレート) |
|
|
(parallelism TS)
|
ファンクタを適用し、非順序でリダクションを行う
(関数テンプレート) |