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) |
Contents |
[edit] 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.
|
[edit] 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.
[edit] 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).
[edit] 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.
[edit] 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.
[edit] 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()