Namensräume
Varianten
Aktionen

std::experimental::parallel::reduce

Von cppreference.com
 
 
 
 
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) Wie reduce(first, last, typename std::iterator_traits<InputIt>::value_type{}).
3) Wie reduce(first, last, init, std::plus<>()).
5) Reduziert den Bereich [firstlast), möglicherweise permutiert und in nicht spezifizierter Weise aggregiert, zusammen mit dem Anfangswert init über binary_op.
2,4,6) Dasselbe wie (1,3,5), aber gemäß policy ausgeführt.

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

Das Verhalten ist undefiniert, wenn binary_op ein Element modifiziert oder einen Iterator in [firstlast) ungültig macht.

Inhalt

[edit] Parameter

first, last - der Bereich von Elementen, auf die der Algorithmus angewendet wird
init - der Anfangswert der generalisierten Summe
policy - die Ausführungsrichtlinie
binary_op - binäre Funktionsobjekt, das in nicht spezifizierter Reihenfolge auf das Ergebnis des Dereferenzierens der Eingabeiteratoren, die Ergebnisse anderer binary_op und init angewendet wird
Typanforderungen
-
InputIt muss die Anforderungen von LegacyInputIterator erfüllen.

[edit] Rückgabewert

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

wobei die generalisierte Summe GSUM(op, a1, ..., aN) wie folgt definiert ist

  • wenn N=1, a1
  • wenn N > 1, op(GSUM(op, b1, ..., bK), GSUM(op, bM, ..., bN)) wobei
  • b1, ..., bN jede Permutation von a1, ..., aN sein kann und
  • 1 < K+1 = M ≤ N

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

[edit] Komplexität

O(last - first) Anwendungen von binary_op.

[edit] Ausnahmen

  • Wenn die Ausführung einer Funktion, die als Teil des Algorithmus aufgerufen wird, eine Ausnahme auslöst,
  • wenn policy parallel_vector_execution_policy ist, wird std::terminate aufgerufen.
  • wenn policy sequential_execution_policy oder parallel_execution_policy ist, endet der Algorithmus mit einer exception_list, die alle nicht abgefangenen Ausnahmen enthält. Wenn nur eine nicht abgefangene Ausnahme vorhanden war, kann der Algorithmus diese erneut auslösen, ohne sie in exception_list zu verpacken. Es ist nicht spezifiziert, wie viel Arbeit der Algorithmus vor der Rückkehr nach der ersten aufgetretenen Ausnahme leistet.
  • wenn policy ein anderer Typ ist, ist das Verhalten implementierungsabhängig.
  • Wenn der Algorithmus Speicher nicht zuweisen kann (weder für sich selbst noch zum Erstellen einer exception_list bei der Behandlung einer Benutzerausnahme), wird std::bad_alloc ausgelöst.

[edit] Hinweise

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

  • Wenn policy eine Instanz von sequential_execution_policy ist, werden alle Operationen im aufrufenden Thread durchgeführt.
  • Wenn policy eine Instanz von parallel_execution_policy ist, können Operationen in einer nicht spezifizierten Anzahl von Threads ausgeführt werden, die indeterminately sequenziert sind.
  • Wenn policy eine Instanz von parallel_vector_execution_policy ist, kann die Ausführung sowohl parallelisiert als auch vektorisiert werden: Funktionsgrenzen werden nicht beachtet und Benutzercode kann beliebig überlappt und kombiniert werden (insbesondere bedeutet dies, dass ein vom Benutzer bereitgestellter Callable keine Mutexsperre erwerben darf, um auf eine freigegebene Ressource zuzugreifen).

[edit] Beispiel

reduce ist die Out-of-Order-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

[edit] Siehe auch

summiert oder faltet eine Reihe von Elementen
(Funktionstemplate) [bearbeiten]
Wendet eine Funktion auf einen Elementbereich an und speichert die Ergebnisse in einem Zielbereich
(Funktionstempelat) [edit]
(parallelism TS)
wendet ein Funktor an, dann Reduzierung außer Reihenfolge
(Funktionale Vorlage) [edit]