Namespaces
Variants

std::execution:: bulk, std::execution:: bulk_chunked, std::execution:: bulk_unchunked

From cppreference.net
Definido en el encabezado <execution>
std :: execution :: sender

auto bulk ( std :: execution :: sender auto input,
std:: integral auto size,
auto && policy,
std:: invocable < decltype ( size ) ,

/*values-sent-by*/ ( input ) ... > function ) ;
(1) (desde C++26)
std :: execution :: sender

auto bulk_chunked ( std :: execution :: sender auto input,
std:: integral auto size,
auto && policy,
std:: invocable < decltype ( size ) , decltype ( size ) ,

/*values-sent-by*/ ( input ) ... > function2 ) ;
(2) (desde C++26)
std :: execution :: sender

auto bulk_unchunked ( std :: execution :: sender auto input,
std:: integral auto size,
std:: invocable < decltype ( size ) , decltype ( size ) ,

/*values-sent-by*/ ( input ) ... > function ) ;
(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()