std::experimental::parallel:: reduce
|
Défini dans l'en-tête
<experimental/numeric>
|
||
|
template
<
class
InputIt
>
typename
std::
iterator_traits
<
InputIt
>
::
value_type
reduce
(
|
(1) | (TS parallélisme) |
|
template
<
class
ExecutionPolicy,
class
InputIterator
>
typename
std::
iterator_traits
<
InputIt
>
::
value_type
reduce
(
|
(2) | (TS parallélisme) |
|
template
<
class
InputIt,
class
T
>
T reduce ( InputIt first, InputIt last, T init ) ; |
(3) | (TS parallélisme) |
|
template
<
class
ExecutionPolicy,
class
InputIt,
class
T
>
T reduce ( ExecutionPolicy && policy, InputIt first, InputIt last, T init ) ; |
(4) | (TS parallélisme) |
|
template
<
class
InputIt,
class
T,
class
BinaryOp
>
T reduce ( InputIt first, InputIt last, T init, BinaryOp binary_op ) ; |
(5) | (TS parallélisme) |
|
template
<
class
ExecutionPolicy,
class
InputIt,
class
T,
class
BinaryOp
>
T reduce
(
ExecutionPolicy
&&
policy,
|
(6) | (TS parallélisme) |
[
first
,
last
)
, potentiellement permutée et agrégée 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 n'est pas défini si
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 |
| binary_op | - | le FunctionObject binaire qui sera appliqué dans un ordre non spécifié au résultat du déréférencement des itérateurs d'entrée, 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 * first , * ( first + 1 ) , ... * ( 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 éléments de la plage peuvent être regroupés et réorganisés dans un ordre arbitraire.
Complexité
O(last - first) applications de 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
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équencée 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 des corps de fonction ne sont pas respectées et le code utilisateur peut être chevauché et combiné de manière arbitraire (ce qui implique notamment qu'un Callable fourni par l'utilisateur ne doit pas acquérir de mutex pour accéder à une ressource partagée).
Exemple
reduce est la version non ordonnée de 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"; } }
Sortie possible :
std::accumulate result 5000003.50000 took 12.7365 ms parallel::reduce result 5000003.50000 took 5.06423 ms
Voir aussi
|
additionne ou plie une plage d'éléments
(modèle de fonction) |
|
|
applique une fonction à une plage d'éléments, stockant les résultats dans une plage de destination
(modèle de fonction) |
|
|
(parallelism TS)
|
applique un foncteur, puis réduit de manière non ordonnée
(modèle de fonction) |