std::execution::bulk, std::execution::bulk_chunked, std::execution::bulk_unchunked
Defined in header <execution>
|
||
std::execution::sender auto bulk( std::execution::sender auto input, |
(1) | (since C++26) |
std::execution::sender auto bulk_chunked( std::execution::sender auto input, |
(2) | (since C++26) |
std::execution::sender auto bulk_unchunked( std::execution::sender auto input, |
(3) | (since C++26) |
Parameters
input | - | sender which once executed sends the values upon which the function executes |
policy | - | the execution policy attached to function/function2 |
function | - | invocable to be called for every index in range [ 0, size) , passing also the values produced by the input sender
|
function2 | - | same as function but called with a pair of indices ( b, e) , with b < e , so that, for each index i in range [ [0, size) there is exactly one call to function2 so that b <= i < e.
|
Return value
Returns a sender describing the task graph described by the input sender, with an added node of invoking the provided function with indices in range [
0,
size)
, passing also the values sent by the input sender as arguments.
function/function2 is guaranteed to not begin executing until the returned sender is started.
Error completions
All errors passed in by input are forwarded.
In addition, the sender is allowed to complete with an std::exception_ptr error that contains:
- any exception thrown by function
- std::bad_alloc if the implementation fails to allocate required resources
- an exception derived from std::runtime_error for other internal errors (e.g., cannot propagate the exception from the execution context to the caller).
Cancellation
The uncustomized std::execution::bulk
, std::execution::bulk_chunk
and std::execution::bulk_unchunked
forward the stopped completion signal from input. They do not provide additional mechanism to produce stopped completion signal.
Notes
When calling std::execution::bulk
and std::execution::bulk_chunked
, different invocations of function/function2 may happen on the same execution agent.
When calling std::execution::bulk_unchunked
, different invocations of function must happen on different execution agents.
The default implementation of std::execution::bulk
is based on std::execution::bulk_chunked
. While customizing std::execution::bulk
is possible, it is expected that most of the time only std::execution::bulk_chunked
is customized.
Without a customization of std::execution::bulk
and std::execution::bulk_chunked
, the behavior of std::execution::bulk
and std::execution::bulk_chunk
is to execute function serially, which is not particularly useful. Implementations are expected to have customizations that would make running std::execution::bulk
and std::execution::bulk_chunked
on different schedulers more useful.
std::execution::bulk_unchunked
is meant to be used whenever function may have dependencies between different invocations, and it requires concurrent forward progress guarantees (parallel forward progress is not enough). Running std::execution::bulk_unchunked
with a size of 1000 will require 1000 execution agents (e.g., threads) to run concurrently.
std::execution::bulk_unchunked
does not require an execution policy, as is already expected for function to be able to run concurrently.
Examples
Possible usage of 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 describes the work described by calling a function to // get a coefficient `a`, and using it to execute // y[i] = a * x[i] + y[i] // for each `i` in range [0, x.size())
Possible usage of 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); }); // the atomic object will not be touched 100000 times; will execute faster than bulk()