C++26 引入的 Executors 框架以 sender/receiver/scheduler 三核心模型为基础,重塑异步编程范式。该模型将异步任务描述为惰性 sender,通过算法组合构建执行图,支持跨执行资源(如线程池、GPU)无缝迁移,避免传统 future/promise 的动态分配与同步开销。相较 C++17 并行算法或 TBB,sender/receiver 提供零分配编译期优化与精确调度控制,适用于高性能系统如游戏渲染或服务器 IO。
核心在于 scheduler 抽象执行资源,sender 表示惰性任务图,receiver 处理完成信号(值 / 错误 / 停止)。典型流程:从 scheduler 获取 schedule sender,管道式附加 then/bulk/when_all 等适配器,最终 sync_wait 消费结果。例如,NVIDIA stdexec 库中 static_thread_pool sch = pool.get_scheduler (); auto snd = schedule (sch) | then ({compute (); }) | bulk (N, [](size_t i){ process (i); }); sync_wait (snd); 此处 bulk 实现并行循环,shape 为线程数,优于 TBB parallel_for 的隐式调度。
实践证明,该模型在 Vulkan 渲染启动加速中显著优于串行加载。Mathieu Ropert 博客实验显示,着色器编译与纹理解压并行后,Debug 模式从 4-5s 降至 900ms,Release 至 200ms,利用 9 线程处理 6 张 PNG 与 2 个 SPIRV。TBB parallel_invoke 等价于 when_all (schedule | then (task)),但 stdexec 支持 continues_on (sch) 显式上下文切换,避免 bulk 串行退化(需额外 continues_on 提醒执行器)。
自定义异步调度需实现 scheduler 概念:提供 schedule () 返回 sender,支持 get_completion_scheduler<set_value_t>() 返回自身,确保完成在指定资源。示例线程池 scheduler:
struct custom_thread_pool_scheduler {
using scheduler_concept = std::execution::scheduler_t;
auto schedule() const noexcept {
return std::execution::schedule(this->pool_scheduler()); // 转发到内部池
}
auto query(std::execution::get_completion_scheduler_t<std::execution::set_value_t>) const noexcept {
return *this;
}
// 添加 get_forward_progress_guarantee: parallel
};
集成 GPU:继承 scheduler,使用 CUDA stream,transform_sender 插入同步点。P2300R10 提案强调 domain 标签(如 cpu_domain/cuda_domain)自定义算法行为,避免跨域类型擦除。
落地参数清单:
- 线程池大小:CPU 核数 * 1.5(e.g., 16 核用 24),bulk shape = 核数,避免超载。
- 超时 / 取消:let_stopped (snd, []{ co_return std::stop_token::never_stop_token {}; }),阈值 5s(服务器 IO),监控 stop_requested ()。
- Bulk 粒度:cutoff=128(小任务串行),shape = 数据块数 / 切片大小。
- 迁移策略:starts_on (io_sched, parse) | continues_on (cpu_sched, bulk),IO 专用 1-2 线程。
- 分配器:with_allocator (pinned_allocator),GPU 需固定内存。
监控要点:
- 指标:完成延迟(sync_wait 时间)、代理数(forward_progress_guarantee::parallel 验证)、资源峰值(CPU 利用率 > 80%、内存 < 峰值 1.5x)。
- 工具:Optick 集成 tbb::task_scheduler_observer 等价 sender 探针,日志 get_completion_scheduler 追踪域。
- 回滚:若编译超时(MSVC +5s),fallback TBB;异常捕获 let_error 统一处理。
风险:概念陡峭(环境查询、domain 嵌套),需 C++23+;模板实例化增编译时(模块缓解)。生产验证:Meta rsys 视频服务亿级 QPS,NVIDIA HPC 库证明零分配融合。
资料来源:Mathieu Ropert 博客(https://mropert.github.io/2025/11/21/trying_out_stdexec/)“TBB 与 stdexec 对比加速 Vulkan 启动”;P2300R10 提案(https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2300r10.html)定义模型与算法。
(正文 1028 字)