Namespaces
Variants

std::experimental::parallel:: reduce

From cppreference.net
ヘッダーで定義 <experimental/numeric>
template < class InputIt >

typename std:: iterator_traits < InputIt > :: value_type reduce (

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

typename std:: iterator_traits < InputIt > :: value_type reduce (

ExecutionPolicy && policy, InputIt first, InputIt last ) ;
(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,

InputIt first, InputIt last, T init, BinaryOp binary_op ) ;
(6) (parallelism TS)
1) reduce ( first, last, typename std:: iterator_traits < InputIt > :: value_type { } ) と同じです。
3) 次と同じ reduce ( first, last, init, std:: plus <> ( ) )
5) 範囲 [ first , last ) を、指定されない方法で並べ替えおよび集約された可能性のある状態で、初期値 init と共に binary_op に対して縮約します。
2,4,6) (1,3,5) と同様ですが、 policy に従って実行されます。

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)
ファンクタを適用し、非順序でリダクションを行う
(関数テンプレート)