std::execution::bulk, std::execution::bulk_chunked, std::execution::bulk_unchunked

来自cppreference.com
< cpp‎ | execution
 
 
 
在标头 <execution> 定义
std::execution::sender

auto bulk( std::execution::sender auto input,
           std::integral auto size,
           auto&& policy,
           std::invocable<decltype(size),

                          /*values-sent-by*/(input)...> function );
(1) (C++26 起)
std::execution::sender

auto bulk_chunked( std::execution::sender auto input,
                   std::integral auto size,
                   auto&& policy,
                   std::invocable<decltype(size), decltype(size),

                                  /*values-sent-by*/(input)...> function2 );
(2) (C++26 起)
std::execution::sender

auto bulk_unchunked( std::execution::sender auto input,
                     std::integral auto size,
                     std::invocable<decltype(size), decltype(size),

                                    /*values-sent-by*/(input)...> function );
(3) (C++26 起)

目录

[编辑] 参数

input - 发送器,一旦执行就将发送函数执行所需的值
policy - 附属于 function/function2执行策略
function - 可调用体,将为范围 [0size) 中的每个索引调用,还会传递输入发送器产生的值
function2 - function,但以一对索引 (be) 调用,其中 b < e,使得对于范围 [0size) 中的每个索引 i,存在恰好一次对 function2 的调用满足 b <= i < e

[编辑] 返回值

返回一个发送器,它描述输入发送器所描述的任务图,并添加一个节点,以范围 [0size) 中的索引调用所提供的函数,还把输入发送器所发送的值作为实参传递给它。

function/function2 保证在返回的发送器启动后才启动执行。

[编辑] 错误完成

input 传入的所有错误都被转发。

此外,允许发送器以一个包含以下之一的 std::exception_ptr 错误完成:

  • function 抛出的任何异常
  • 当实现分配所需资源失败时的 std::bad_alloc
  • 派生自 std::runtime_error 的表示其他内部错误的异常(例如,无法把来自执行上下文的异常传播给调用方)

[编辑] 取消

未定制化的 std::execution::bulkstd::execution::bulk_chunkstd::execution::bulk_unchunked 会转发来自 input 的停止完成信号。它们并不提供额外的产生停止完成信号机制。

[编辑] 注解

调用 std::execution::bulkstd::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::bulkstd::execution::bulk_chunked 的定制化时,std::execution::bulkstd::execution::bulk_chunk 的行为是串行执行 function,这并没什么用。预期各个实现提供一些定制,使得 std::execution::bulkstd::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() 更快