std::experimental::parallel:: transform_reduce
|
Definiert im Header
<experimental/numeric>
|
||
|
template
<
class
InputIt,
class
UnaryOp,
class
T,
class
BinaryOp
>
T transform_reduce
(
InputIt first, InputIt last,
|
(1) | (Parallelism TS) |
|
template
<
class
ExecutionPolicy,
class
InputIt,
class
UnaryOp,
class
T,
class
BinaryOp
>
|
(2) | (Parallelism TS) |
Wendet
unary_op
auf jedes Element im Bereich
[
first
,
last
)
an und reduziert die Ergebnisse (möglicherweise umgeordnet und auf nicht spezifizierte Weise aggregiert) zusammen mit dem Initialwert
init
über
binary_op
.
Das Verhalten ist nicht deterministisch, wenn binary_op nicht assoziativ oder nicht kommutativ ist.
Das Verhalten ist undefiniert, falls
unary_op
oder
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 |
| unary_op | - | unärer FunctionObject , der auf jedes Element des Eingabebereichs angewendet wird. Der Rückgabetyp muss als Eingabe für binary_op akzeptabel sein |
| binary_op | - | binärer FunctionObject , der in nicht spezifizierter Reihenfolge auf die Ergebnisse von unary_op , 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 unary_op ( * first ) , unary_op ( * ( first + 1 ) ) , ... unary_op ( * ( last - 1 ) ) über binary_op , wobei die verallgemeinerte Summe GSUM(op, a 1 , ..., a N ) wie folgt definiert ist:
- wenn N = 1 , a 1 ,
- wenn N > 1 , op(GSUM(op, b 1 , ..., b K ), GSUM(op, b M , ..., b N )) wobei
-
- b 1 , ..., b N kann eine beliebige Permutation von a1, ..., aN sein und
- 1 < K + 1 = M ≤ N
mit anderen Worten, die Ergebnisse von unary_op können in beliebiger Reihenfolge gruppiert und angeordnet werden.
Komplexität
O(last - first) Anwendungen jeweils von unary_op und binary_op .
Ausnahmen
- Wenn die Ausführung einer Funktion, die als Teil des Algorithmus aufgerufen wird, eine Ausnahme auslöst,
-
-
falls
policygleichparallel_vector_execution_policyist, wird std::terminate aufgerufen. -
falls
policygleichsequential_execution_policyoderparallel_execution_policyist, 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 inexception_listzu verpacken. Es ist nicht spezifiziert, wie viel Arbeit der Algorithmus ausführt, bevor er nach der ersten aufgetretenen Ausnahme zurückkehrt. -
falls
policyeinen anderen Typ hat, ist das Verhalten implementierungsdefiniert.
-
falls
-
Wenn der Algorithmus keinen Speicher allokieren kann (entweder für sich selbst oder um eine
exception_listbei der Behandlung einer Benutzerausnahme zu konstruieren), wird std::bad_alloc geworfen.
Hinweise
unary_op wird nicht auf init angewendet.
Wenn der Bereich leer ist, init wird unverändert zurückgegeben.
-
Wenn
policyeine Instanz vonsequential_execution_policyist, werden alle Operationen im aufrufenden Thread ausgeführt. -
Wenn
policyeine Instanz vonparallel_execution_policyist, können Operationen in einer nicht spezifizierten Anzahl von Threads ausgeführt werden, in unbestimmter Reihenfolge zueinander. -
Wenn
policyeine Instanz vonparallel_vector_execution_policyist, 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 benutzerdefiniertes Callable keinen Mutex zur Zugriff auf eine gemeinsam genutzte Ressource anfordern darf).
Beispiel
transform_reduce kann verwendet werden, um std::inner_product zu parallelisieren:
#include <boost/iterator/zip_iterator.hpp> #include <boost/tuple.hpp> #include <experimental/execution_policy> #include <experimental/numeric> #include <functional> #include <iostream> #include <iterator> #include <vector> int main() { std::vector<double> xvalues(10007, 1.0), yvalues(10007, 1.0); double result = std::experimental::parallel::transform_reduce( std::experimental::parallel::par, boost::iterators::make_zip_iterator( boost::make_tuple(std::begin(xvalues), std::begin(yvalues))), boost::iterators::make_zip_iterator( boost::make_tuple(std::end(xvalues), std::end(yvalues))), [](auto r) { return boost::get<0>(r) * boost::get<1>(r); } 0.0, std::plus<>() ); std::cout << result << '\n'; }
Ausgabe:
10007
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)
|
ähnlich zu
std::accumulate
, jedoch außerhalb der Reihenfolge
(Funktions-Template) |