std::execution::bulk, std::execution::bulk_chunked, std::execution::bulk_unchunked
定义于头文件 <execution> |
||
std::execution::sender auto bulk( std::execution::sender auto input, |
(1) | (C++26 起) |
std::execution::sender auto bulk_chunked( std::execution::sender auto input, |
(2) | (C++26 起) |
std::execution::sender auto bulk_unchunked( std::execution::sender auto input, |
(3) | (C++26 起) |
目录 |
[编辑] 参数
input | - | 发送者,一旦执行便发送函数执行所需的值 |
policy | - | 附在 function/function2 上的执行策略 |
function | - | 可调用对象,针对范围 [ 0, size) 内的每个索引调用,同时传递输入发送器产生的值。 |
function2 | - | 与 function 相同,但使用一对索引 ( b, e) 调用,其中 b < e ,以便对于范围 [ [0, size) 中的每个索引 i ,恰好有一个对 function2 的调用使得 b <= i < e。 |
[编辑] 返回值
返回一个发送器,描述由输入发送器描述的任务图,并添加了一个节点,用于调用所提供的函数,索引范围为 [
0,
size)
,同时将输入发送器发送的值作为参数传递。
保证 function/function2 不会在返回的发送器启动之前开始执行。
[编辑] 错误完成
所有由 input 传递进来的错误都会被转发。
此外,发送器可以以包含以下内容的 std::exception_ptr 错误完成:
- 由 function 抛出的任何异常
- 如果实现未能分配所需资源,则为 std::bad_alloc
- 其他内部错误(例如,无法将异常从执行上下文传播到调用者)的派生自 std::runtime_error 的异常。
[编辑] 取消
未定制的 std::execution::bulk
、std::execution::bulk_chunk
和 std::execution::bulk_unchunked
会转发来自 input 的停止完成信号。它们不提供额外的机制来生成停止完成信号。
[编辑] 注意
当调用 std::execution::bulk
和 std::execution::bulk_chunked
时,function/function2 的不同调用可能发生在同一个执行代理上。
当调用 std::execution::bulk_unchunked
时,function 的不同调用必须发生在不同的执行代理上。
std::execution::bulk
的默认实现基于 std::execution::bulk_chunked
。虽然可以定制 std::execution::bulk
,但预计大多数情况下只定制 std::execution::bulk_chunked
。
在没有定制 std::execution::bulk
和 std::execution::bulk_chunked
的情况下,std::execution::bulk
和 std::execution::bulk_chunk
的行为是串行执行 function,这并非特别有用。预计实现会有定制,使得在不同调度器上运行 std::execution::bulk
和 std::execution::bulk_chunked
更有用。
std::execution::bulk_unchunked
旨在用于 function 可能在不同调用之间存在依赖关系,并且需要并发前向进度保证(并行前向进度不足以满足)的情况。以 1000 的大小运行 std::execution::bulk_unchunked
将需要 1000 个执行代理(例如,线程)并发运行。
std::execution::bulk_unchunked
不需要执行策略,因为已经预期 function 能够并发运行。
[编辑] 示例
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())
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()