std::experimental::parallel:: transform_reduce
|
Défini dans l'en-tête
<experimental/numeric>
|
||
|
template
<
class
InputIt,
class
UnaryOp,
class
T,
class
BinaryOp
>
T transform_reduce
(
InputIt first, InputIt last,
|
(1) | (TS parallélisme) |
|
template
<
class
ExecutionPolicy,
class
InputIt,
class
UnaryOp,
class
T,
class
BinaryOp
>
|
(2) | (TS parallélisme) |
Applique
unary_op
à chaque élément dans l'intervalle
[
first
,
last
)
et réduit les résultats (éventuellement permutés et agrégés de manière non spécifiée) avec la valeur initiale
init
via
binary_op
.
Le comportement est non déterministe si binary_op n'est pas associatif ou n'est pas commutatif.
Le comportement est indéfini si
unary_op
ou
binary_op
modifie un élément quelconque ou invalide un itérateur dans
[
first
,
last
)
.
Table des matières |
Paramètres
| first, last | - | la plage d'éléments à laquelle appliquer l'algorithme |
| init | - | la valeur initiale de la somme généralisée |
| policy | - | la politique d'exécution |
| unary_op | - | FunctionObject unaire qui sera appliqué à chaque élément de la plage d'entrée. Le type de retour doit être acceptable en entrée pour binary_op |
| binary_op | - | FunctionObject binaire qui sera appliqué dans un ordre non spécifié aux résultats de unary_op , aux résultats d'autres binary_op et à init |
| Exigences de type | ||
-
InputIt
doit satisfaire aux exigences de
LegacyInputIterator
.
|
||
Valeur de retour
Somme généralisée de init et unary_op ( * first ) , unary_op ( * ( first + 1 ) ) , ... unary_op ( * ( last - 1 ) ) sur binary_op , où la somme généralisée GSUM(op, a 1 , ..., a N ) est définie comme suit :
- si N = 1 , a 1 ,
- si N > 1 , op(GSUM(op, b 1 , ..., b K ), GSUM(op, b M , ..., b N )) où
-
- b 1 , ..., b N peut être n'importe quelle permutation de a1, ..., aN et
- 1 < K + 1 = M ≤ N
en d'autres termes, les résultats de unary_op peuvent être groupés et arrangés dans un ordre arbitraire.
Complexité
O(last - first) applications de chacune des fonctions unary_op et binary_op .
Exceptions
- Si l'exécution d'une fonction invoquée dans le cadre de l'algorithme lève une exception,
-
-
si
policyestparallel_vector_execution_policy, std::terminate est appelé. -
si
policyestsequential_execution_policyouparallel_execution_policy, l'algorithme se termine avec une exception_list contenant toutes les exceptions non capturées. S'il n'y avait qu'une seule exception non capturée, l'algorithme peut la relancer sans l'encapsuler dansexception_list. Il n'est pas spécifié combien de travail l'algorithme effectuera avant de retourner après la première exception rencontrée. -
si
policyest d'un autre type, le comportement est défini par l'implémentation.
-
si
-
Si l'algorithme ne parvient pas à allouer de la mémoire (soit pour lui-même, soit pour construire une
exception_listlors de la gestion d'une exception utilisateur), std::bad_alloc est levée.
Notes
unary_op n'est pas appliqué à init .
Si la plage est vide, init est retourné, inchangé.
-
Si
policyest une instance desequential_execution_policy, toutes les opérations sont exécutées dans le thread appelant. -
Si
policyest une instance deparallel_execution_policy, les opérations peuvent être exécutées dans un nombre non spécifié de threads, de manière séquentiellement indéterminée les unes par rapport aux autres. -
Si
policyest une instance deparallel_vector_execution_policy, l'exécution peut être parallélisée et vectorisée : les limites du corps de fonction ne sont pas respectées et le code utilisateur peut être entrelacé et combiné de manière arbitraire (cela implique notamment qu'un Callable fourni par l'utilisateur ne doit pas acquérir de mutex pour accéder à une ressource partagée).
Exemple
transform_reduce peut être utilisé pour paralléliser std::inner_product :
#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'; }
Sortie :
10007
Voir aussi
|
additionne ou plie une série d'éléments
(modèle de fonction) |
|
|
applique une fonction à une série d'éléments, stockant les résultats dans une plage de destination
(modèle de fonction) |
|
|
(parallelism TS)
|
similaire à
std::accumulate
, mais sans ordre
(modèle de fonction) |