std::experimental::parallel:: reduce
|
Definido en el encabezado
<experimental/numeric>
|
||
|
template
<
class
InputIt
>
typename
std::
iterator_traits
<
InputIt
>
::
value_type
reduce
(
|
(1) | (parallelism TS) |
|
template
<
class
ExecutionPolicy,
class
InputIterator
>
typename
std::
iterator_traits
<
InputIt
>
::
value_type
reduce
(
|
(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,
|
(6) | (parallelism TS) |
[
first
,
last
)
, posiblemente permutado y agregado de manera no especificada, junto con el valor inicial
init
sobre
binary_op
.
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
policyesparallel_vector_execution_policy, std::terminate es llamado. -
si
policyessequential_execution_policyoparallel_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 enexception_list. No está especificado cuánto trabajo realizará el algoritmo antes de retornar después de que se encontró la primera excepción. -
si
policyes de algún otro tipo, el comportamiento está definido por la implementación.
-
si
-
Si el algoritmo no puede asignar memoria (ya sea para sí mismo o para construir una
exception_listal manejar una excepción de usuario), std::bad_alloc es lanzada.
Notas
Si el rango está vacío, init se devuelve, sin modificar.
-
Si
policyes una instancia desequential_execution_policy, todas las operaciones se realizan en el hilo de llamada. -
Si
policyes una instancia deparallel_execution_policy, las operaciones pueden realizarse en un número no especificado de hilos, secuenciadas indeterminadamente entre sí. -
Si
policyes una instancia deparallel_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) |