std::experimental::parallel::reduce
| Definiert im Header <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), möglicherweise permutiert und in nicht spezifizierter Weise aggregiert, zusammen mit dem Anfangswert init über binary_op.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 [first, last) 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
policyparallel_vector_execution_policyist, wird std::terminate aufgerufen. - wenn
policysequential_execution_policyoderparallel_execution_policyist, 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 inexception_listzu verpacken. Es ist nicht spezifiziert, wie viel Arbeit der Algorithmus vor der Rückkehr nach der ersten aufgetretenen Ausnahme leistet. - wenn
policyein anderer Typ ist, ist das Verhalten implementierungsabhängig.
- wenn
- Wenn der Algorithmus Speicher nicht zuweisen kann (weder für sich selbst noch zum Erstellen einer
exception_listbei der Behandlung einer Benutzerausnahme), wird std::bad_alloc ausgelöst.
[edit] Hinweise
Wenn der Bereich leer ist, wird init unverändert zurückgegeben.
- Wenn
policyeine Instanz vonsequential_execution_policyist, werden alle Operationen im aufrufenden Thread durchgeführt. - Wenn
policyeine Instanz vonparallel_execution_policyist, können Operationen in einer nicht spezifizierten Anzahl von Threads ausgeführt werden, die indeterminately sequenziert sind. - Wenn
policyeine Instanz vonparallel_vector_execution_policyist, 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) | |
| Wendet eine Funktion auf einen Elementbereich an und speichert die Ergebnisse in einem Zielbereich (Funktionstempelat) | |
| (parallelism TS) |
wendet ein Funktor an, dann Reduzierung außer Reihenfolge (Funktionale Vorlage) |