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 描述了通过调用函数获取系数 `a`,并使用该系数执行 // y[i] = a * x[i] + y[i] // 对于每个在范围 [0, x.size()) 内的 `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); }); // 原子对象不会被访问10万次;执行速度将比 bulk() 更快