Namespaces
Variants

std::experimental::parallel:: reduce

From cppreference.net
Definiert im Header <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) Gleich wie reduce ( first, last, typename std:: iterator_traits < InputIt > :: value_type { } ) .
3) Gleich wie reduce ( first, last, init, std:: plus <> ( ) ) .
5) Reduziert den Bereich [ first , last ) , möglicherweise permutiert und auf nicht spezifizierte Weise aggregiert, zusammen mit dem Anfangswert init über binary_op .
2,4,6) Gleich wie (1,3,5) , aber ausgeführt gemäß policy .

Das Verhalten ist nicht deterministisch, wenn binary_op nicht assoziativ oder nicht kommutativ ist.

Das Verhalten ist undefiniert, falls binary_op irgendein Element modifiziert oder irgendeinen Iterator im Bereich [ first , last ) ungültig macht.

Inhaltsverzeichnis

Parameter

first, last - der Bereich der Elemente, auf die der Algorithmus angewendet werden soll
init - der Anfangswert der generalisierten Summe
policy - die Ausführungsrichtlinie
binary_op - binäres FunctionObject , das in nicht spezifizierter Reihenfolge auf das Ergebnis der Dereferenzierung der Eingabe-Iteratoren, die Ergebnisse anderer binary_op und init angewendet wird
Typanforderungen
-
InputIt muss die Anforderungen von LegacyInputIterator erfüllen.

Rückgabewert

Verallgemeinerte Summe von init und * first , * ( first + 1 ) , ... * ( last - 1 ) über binary_op ,

wobei der generalisierte Summenoperator GSUM(op, a 1 , ..., a N ) wie folgt definiert ist:

  • falls N=1 , a 1
  • falls N > 1 , op(GSUM(op, b 1 , ..., b K ), GSUM(op, b M , ..., b N )) wobei
  • b 1 , ..., b N kann jede Permutation von a1, ..., aN sein und
  • 1 < K+1 = M ≤ N

mit anderen Worten, die Elemente des Bereichs können in beliebiger Reihenfolge gruppiert und neu angeordnet werden.

Komplexität

O(last - first) Anwendungen von binary_op .

Ausnahmen

  • Wenn die Ausführung einer Funktion, die als Teil des Algorithmus aufgerufen wird, eine Exception wirft,
  • falls policy gleich parallel_vector_execution_policy ist, wird std::terminate aufgerufen.
  • falls policy gleich sequential_execution_policy oder parallel_execution_policy ist, beendet sich der Algorithmus mit einer exception_list , die alle nicht abgefangenen Ausnahmen enthält. Falls es nur eine nicht abgefangene Ausnahme gab, darf der Algorithmus diese erneut werfen, ohne sie in exception_list zu verpacken. Es ist nicht spezifiziert, wie viel Arbeit der Algorithmus ausführt, bevor er nach der ersten aufgetretenen Ausnahme zurückkehrt.
  • falls policy ein anderer Typ ist, ist das Verhalten implementierungsdefiniert.
  • Wenn der Algorithmus keinen Speicher allokieren kann (entweder für sich selbst oder um eine exception_list bei der Behandlung einer Benutzerausnahme zu konstruieren), std::bad_alloc wird geworfen.

Hinweise

Wenn der Bereich leer ist, init wird unverändert zurückgegeben.

  • Wenn policy eine Instanz von sequential_execution_policy ist, werden alle Operationen im aufrufenden Thread ausgeführt.
  • Wenn policy eine Instanz von parallel_execution_policy ist, können Operationen in einer nicht spezifizierten Anzahl von Threads ausgeführt werden, in unbestimmter Reihenfolge zueinander.
  • Wenn policy eine Instanz von parallel_vector_execution_policy ist, kann die Ausführung sowohl parallelisiert als auch vektorisiert werden: Funktionskörpergrenzen werden nicht beachtet und Benutzercode kann auf beliebige Weise überlappt und kombiniert werden (dies impliziert insbesondere, dass ein benutzerbereitgestelltes Callable keinen Mutex zur Zugriff auf eine gemeinsam genutzte Ressource anfordern darf).

Beispiel

reduce ist die nicht geordnete Version von 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";
    }
}

Mögliche Ausgabe:

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

Siehe auch

summiert oder faltet eine Reihe von Elementen
(Funktions-Template)
wendet eine Funktion auf eine Reihe von Elementen an und speichert Ergebnisse in einem Zielbereich
(Funktions-Template)
(parallelism TS)
wendet einen Funktor an und reduziert dann außerhalb der Reihenfolge
(Funktions-Template)