web-dev-qa-db-fra.com

Pourquoi std :: reduction a-t-il été ajouté en C++ 17?

Je cherchais une explication détaillée sur la signification de la description "Valeur renvoyée" pour std::reduce, qui, selon cppreference.com, est la suivante:

 enter image description here

Peut-être qu'une fois que je pourrai percevoir correctement l'idée de la section "Valeur de retour", je pourrai mieux déterminer où je devrais choisir std::reduce plutôt que std::accumulate

33
Aria Pahlavan

std::accumulate itère sur le conteneur dans l'ordre où std:reduce pourrait ne pas l'être. Étant donné que la commande n'est pas garantie, std::reduce introduit des exigences supplémentaires: 

Le comportement est non déterministe si binary_op n'est ni associatif ni commutatif. Le comportement n'est pas défini si binary_op modifie un élément ou invalide un itérateur dans [first; dernier], y compris l'itérateur de fin.

Cependant, std::reduce fournit des surcharges prenant en charge la parallélisation qui ne sont pas disponibles avec std::accumulate. std::reduce vous permet de paralléliser automatiquement votre opération, à condition qu'elle réponde aux exigences mentionnées ci-dessus.

29
  • Permettre le parallélisme est la raison principale pour l’ajout de std :: réduire

  • De plus, vous devez vous assurer que l’opération que vous voulez utiliser avec std :: reduction est à la fois associative Et commutative.

    • Par exemple, Addition est associative et donne les mêmes résultats lorsque l'accumulation est effectuée en parallèle à l'aide de std :: Réduire.
      100 + 50 + 40 + 10 = 200(100 + 40) + (50 + 10) = 200

    • Mais la soustraction n'étant pas associative, std :: réduire peut donner des résultats erronés.
      100 - 50 - 40 - 10 = 0 NOT SAME AS (100 - 40) - (50 - 10) = 20

  • Efficacité
    std::vector<double> v(100000, 0.1);double result = std::accumulate(v.begin(), v.end(), 0.0);double result = std::reduce(std::execution::par,v.begin(),v.end()) //Faster

0
kbagal