Defined in header <execution> | ||
std::execution::sender auto bulk( std::execution::senderauto input, | (1) | (since C++26) |
std::execution::sender auto bulk_chunked( std::execution::senderauto input, | (2) | (since C++26) |
std::execution::sender auto bulk_unchunked( std::execution::senderauto input, | (3) | (since C++26) |
Contents |
| input | - | sender which once executed sends the values upon which the function executes |
| policy | - | theexecution policy attached tofunction/function2 |
| function | - | invocable to be called for every index in range[0, size), passing also the values produced by the input sender |
| function2 | - | same asfunction but called with a pair of indices(b, e), withb < e, so that, for each indexi in range[[0, size) there is exactly one call tofunction2 so thatb<= i< e. |
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.
All errors passed in byinput are forwarded.
In addition, the sender is allowed to complete with anstd::exception_ptr error that contains:
The uncustomizedstd::execution::bulk,std::execution::bulk_chunk andstd::execution::bulk_unchunked forward the stopped completion signal frominput. They do not provide additional mechanism to produce stopped completion signal.
When callingstd::execution::bulk andstd::execution::bulk_chunked, different invocations offunction/function2 may happen on the same execution agent.
When callingstd::execution::bulk_unchunked, different invocations offunction must happen on different execution agents.
The default implementation ofstd::execution::bulk is based onstd::execution::bulk_chunked. While customizingstd::execution::bulk is possible, it is expected that most of the time onlystd::execution::bulk_chunked is customized.
Without a customization ofstd::execution::bulk andstd::execution::bulk_chunked, the behavior ofstd::execution::bulk andstd::execution::bulk_chunk is to executefunction serially, which is not particularly useful. Implementations are expected to have customizations that would make runningstd::execution::bulk andstd::execution::bulk_chunked on different schedulers more useful.
std::execution::bulk_unchunked is meant to be used wheneverfunction may have dependencies between different invocations, and it requires concurrent forward progress guarantees (parallel forward progress is not enough). Runningstd::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 forfunction to be able to run concurrently.
Possible usage ofexecution::bulk.
std::vector<double> x;std::vector<double> y;//...senderauto 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 ofexecution::bulk_chunked.
std::vector<std::uint32_t> data= ...;std::atomic<std::uint32_t> sum{0};senderauto 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()