std::execution:: bulk, std::execution:: bulk_chunked, std::execution:: bulk_unchunked
|
Definido en el encabezado
<execution>
|
||
|
std
::
execution
::
sender
auto
bulk
(
std
::
execution
::
sender
auto
input,
|
(1) | (desde C++26) |
|
std
::
execution
::
sender
auto
bulk_chunked
(
std
::
execution
::
sender
auto
input,
|
(2) | (desde C++26) |
|
std
::
execution
::
sender
auto
bulk_unchunked
(
std
::
execution
::
sender
auto
input,
|
(3) | (desde C++26) |
Contenidos |
Parámetros
| input | - | emisor que una vez ejecutado envía los valores sobre los cuales la función se ejecuta |
| policy | - | la política de ejecución asociada a function / function2 |
| function | - |
invocable que será llamado para cada índice en el rango
[
0
,
size
)
, pasando también los valores producidos por el emisor de entrada
|
| function2 | - |
igual que
function
pero llamado con un par de índices
(
b
,
e
)
, con
b < e
, de modo que, para cada índice
i
en el rango
[
[
0
,
size
)
hay exactamente una llamada a
function2
tal que
b
<=
i
<
e
.
|
Valor de retorno
Devuelve un emisor que describe el grafo de tareas descrito por el emisor de entrada, con un nodo adicional que invoca la función proporcionada con índices en el rango
[
0
,
size
)
, pasando también los valores enviados por el emisor de entrada como argumentos.
function / function2 tiene garantizado no comenzar su ejecución hasta que el sender devuelto sea iniciado.
Completaciones de error
Todos los errores pasados por input son reenviados.
Además, se permite al remitente completar con un std::exception_ptr error que contiene:
- cualquier excepción lanzada por function
- std::bad_alloc si la implementación falla al asignar los recursos requeridos
- una excepción derivada de std::runtime_error para otros errores internos (por ejemplo, no se puede propagar la excepción del contexto de ejecución al llamador).
Cancelación
El no personalizado
std::execution::bulk
,
std::execution::bulk_chunk
y
std::execution::bulk_unchunked
reenvían la señal de finalización detenida desde
input
. No proporcionan mecanismos adicionales para generar señales de finalización detenida.
Notas
Al llamar a
std::execution::bulk
y
std::execution::bulk_chunked
, diferentes invocaciones de
function
/
function2
pueden ocurrir en el mismo agente de ejecución.
Al llamar a
std::execution::bulk_unchunked
, diferentes invocaciones de
function
deben ocurrir en diferentes agentes de ejecución.
La implementación predeterminada de
std::execution::bulk
está basada en
std::execution::bulk_chunked
. Si bien es posible personalizar
std::execution::bulk
, se espera que la mayoría de las veces solo se personalice
std::execution::bulk_chunked
.
Sin una personalización de
std::execution::bulk
y
std::execution::bulk_chunked
, el comportamiento de
std::execution::bulk
y
std::execution::bulk_chunk
es ejecutar la
function
en serie, lo cual no es particularmente útil. Se espera que las implementaciones tengan personalizaciones que harían más útil la ejecución de
std::execution::bulk
y
std::execution::bulk_chunked
en diferentes planificadores.
std::execution::bulk_unchunked
está destinado a ser utilizado cuando
function
puede tener dependencias entre diferentes invocaciones, y requiere garantías de progreso concurrente (el progreso paralelo no es suficiente). Ejecutar
std::execution::bulk_unchunked
con un tamaño de 1000 requerirá 1000 agentes de ejecución (por ejemplo, hilos) para ejecutarse concurrentemente.
std::execution::bulk_unchunked
no requiere una política de ejecución, como ya se espera que la
function
pueda ejecutarse concurrentemente.
Ejemplos
Posible uso de
execution::bulk
.
std::vector<double> x; std::vector<double> y; //... sender auto process_elements = just(get_coefficient()) | bulk(x.size(), [&](size_t i, double a) { y[i] = a * x[i] + y[i]; }); // process_elements describe el trabajo definido al llamar a una función para // obtener un coeficiente `a`, y usarlo para ejecutar // y[i] = a * x[i] + y[i] // para cada `i` en el rango [0, x.size())
Posible uso de
execution::bulk_chunked
.
std::vector<std::uint32_t> data = ...; std::atomic<std::uint32_t> sum{0}; sender auto s = bulk_chunked(just(), par, 100000, [&sum, &data](int begin, int end) { auto partial_sum = std::accumulate(data.begin() + begin, data.begin() + end, 0U); sum.fetch_add(partial_sum); }); // el objeto atómico no será accedido 100000 veces; se ejecutará más rápido que bulk()