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/{c|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 描述的工作为:调用某个函数以获得一个系数 `a`, // 然后用它对范围 [0, x.size()) 中的每个 `i` 执行 // y[i] = a * x[i] + y[i]
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); }); // 不会触碰原子对象达 100000 次;执行将比 bulk() 更快