Namespaces
Variants

std::experimental::parallel:: reduce

From cppreference.net
Definido en el encabezado <experimental/numeric>
template < class InputIt >

typename std:: iterator_traits < InputIt > :: value_type reduce (

InputIt first, InputIt last ) ;
(1) (parallelism TS)
template < class ExecutionPolicy, class InputIterator >

typename std:: iterator_traits < InputIt > :: value_type reduce (

ExecutionPolicy && policy, InputIt first, InputIt last ) ;
(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,

InputIt first, InputIt last, T init, BinaryOp binary_op ) ;
(6) (parallelism TS)
1) Igual que reduce ( first, last, typename std:: iterator_traits < InputIt > :: value_type { } ) .
3) Igual que reduce ( first, last, init, std:: plus <> ( ) ) .
5) Reduce el rango [ first , last ) , posiblemente permutado y agregado de manera no especificada, junto con el valor inicial init sobre binary_op .
2,4,6) Igual que (1,3,5) , pero ejecutado según la policy .

El comportamiento es no determinista si binary_op no es asociativo o no es conmutativo.

El comportamiento es indefinido si binary_op modifica cualquier elemento o invalida cualquier iterador en [ first , last ) .

Contenidos

Parámetros

first, last - el rango de elementos al que aplicar el algoritmo
init - el valor inicial de la suma generalizada
policy - la política de ejecución
binary_op - objeto de función binario FunctionObject que se aplicará en orden no especificado al resultado de desreferenciar los iteradores de entrada, los resultados de otros binary_op e init
Requisitos de tipo
-
InputIt debe cumplir con los requisitos de LegacyInputIterator .

Valor de retorno

Suma generalizada de init y * first , * ( first + 1 ) , ... * ( last - 1 ) sobre binary_op ,

donde la suma generalizada GSUM(op, a 1 , ..., a N ) se define de la siguiente manera:

  • si N=1 , a 1
  • si N > 1 , op(GSUM(op, b 1 , ..., b K ), GSUM(op, b M , ..., b N )) donde
  • b 1 , ..., b N puede ser cualquier permutación de a1, ..., aN y
  • 1 < K+1 = M ≤ N

en otras palabras, los elementos del rango pueden agruparse y reorganizarse en orden arbitrario.

Complejidad

O(last - first) aplicaciones de binary_op .

Excepciones

  • Si la ejecución de una función invocada como parte del algoritmo lanza una excepción,
  • si policy es parallel_vector_execution_policy , std::terminate es llamado.
  • si policy es sequential_execution_policy o parallel_execution_policy , el algoritmo termina con una exception_list que contiene todas las excepciones no capturadas. Si solo había una excepción no capturada, el algoritmo puede relanzarla sin envolverla en exception_list . No está especificado cuánto trabajo realizará el algoritmo antes de retornar después de que se encontró la primera excepción.
  • si policy es de algún otro tipo, el comportamiento está definido por la implementación.
  • Si el algoritmo no puede asignar memoria (ya sea para sí mismo o para construir una exception_list al manejar una excepción de usuario), std::bad_alloc es lanzada.

Notas

Si el rango está vacío, init se devuelve, sin modificar.

  • Si policy es una instancia de sequential_execution_policy , todas las operaciones se realizan en el hilo de llamada.
  • Si policy es una instancia de parallel_execution_policy , las operaciones pueden realizarse en un número no especificado de hilos, secuenciadas indeterminadamente entre sí.
  • Si policy es una instancia de parallel_vector_execution_policy , la ejecución puede ser paralelizada y vectorizada: los límites del cuerpo de función no se respetan y el código de usuario puede superponerse y combinarse de manera arbitraria (en particular, esto implica que un Callable proporcionado por el usuario no debe adquirir un mutex para acceder a un recurso compartido).

Ejemplo

reduce es la versión sin orden 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";
    }
}

Salida posible:

std::accumulate result 5000003.50000 took 12.7365 ms
parallel::reduce result 5000003.50000 took 5.06423 ms

Véase también

suma o pliega un rango de elementos
(function template)
aplica una función a un rango de elementos, almacenando resultados en un rango destino
(function template)
(parallelism TS)
aplica un functor, luego reduce fuera de orden
(function template)