ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

oneTBB 流图预定义并发限制详解:`unlimited` 与 `serial` 常量及并发控制实战

oneTBB 流图预定义并发限制详解:`unlimited` 与 `serial` 常量及并发控制实战 并发编程高性能计算【免费下载链接】oneTBBoneAPI Threading Building Blocks (oneTBB)项目地址https://gitcode.com/gh_mirrors/on/oneTBB点击查看免费下载在 oneAPI Threading Building BlocksoneTBB的流图Flow Graph框架中tbb::flow::unlimited与tbb::flow::serial是两个预定义的并发限制常量用于在构造function_node、multifunction_node和async_node时指定节点允许的并发度。本指南基于官方参考文档 predefined_concurrency_limits.rst结合仓库源码include/oneapi/tbb/flow_graph.h、include/oneapi/tbb/detail/_flow_graph_node_impl.h深入讲解这两个常量的语义、底层实现与实战用法。阅读本文后你将能够精准地为流图节点配置并发策略并理解节点内部如何依据并发计数决定接受、排队或拒绝消息。什么是预定义并发限制在 oneTBB 流图中function_node、multifunction_node和async_node的构造函数都接受一个size_t concurrency参数用于声明节点体body最多可以被多少个任务同时执行。为了覆盖最常见的两种场景官方在oneapi/tbb/flow_graph.h头文件中提供了两个预定义常量// Defined in header oneapi/tbb/flow_graph.h namespace oneapi { namespace tbb { namespace flow { std::size_t unlimited /*implementation-defined*/; std::size_t serial /*implementation-defined*/; } // namespace flow } // namespace tbb } // namespace oneapiunlimited允许节点体被任意数量的任务并发调用节点几乎不会因并发度限制而拒绝输入消息。serial只允许节点体被单个任务同时调用同一时刻至多只有一个消息正在执行节点体。说明文档中给出的unlimited、serial以“实现定义implementation-defined”的方式呈现其数值。从当前仓库源码看这两个符号实际由内部枚举提供enum concurrency { unlimited 0, serial 1 };见 include/oneapi/tbb/flow_graph.h 中tbb::detail::d2命名空间并在tbb::flow命名空间下通过using detail::d2::serial;与using detail::d2::unlimited;对外暴露见 include/oneapi/tbb/flow_graph.h。使用时应始终以unlimited、serial符号本身表达意图不要依赖其具体数值。适用节点按参考文档定义这两个常量可作为以下三类节点的构造函数参数function_node单输入、单输出节点对每条输入消息执行一次节点体multifunction_node单输入、多输出端口节点节点体可产生多条输出消息并广播给后继节点async_node输入消息交给异步活动处理的节点。这三类节点的参考文档都明确说明其并发限制可设置为 预定义值例如function_node一节写道“function_node具有用户可设置的并发限制可设置为预定义值之一用户也可提供介于 1 与tbb::flow::unlimited之间的std::size_t数值”见 func_node_cls.rst。语义详解unlimited无限制并发unlimited并发允许节点体任意数量的调用同时执行。每个到达的消息只要节点有空闲的执行槽位实际上由于限制值极大几乎总是满足就会立即触发一次节点体调用并可与其它调用并行运行。它适用于节点体是纯函数、无共享可变状态天然线程安全希望最大化吞吐量、充分占用多核并行能力的场景上游节点快速产生大量独立消息、需要并行消化这些消息的场景。在默认策略下使用unlimited的节点通常不会拒绝输入输入消息能够被及时接受并调度执行。serial串行并发serial并发只允许节点体同时执行一个调用后续到达的消息必须等待当前调用结束后才能进入节点体。它适用于节点体操作共享资源如全局计数器、日志缓冲、外部设备不允许并发访问节点体内部状态无法做到线程安全需要强制串行化需要保证消息按到达顺序处理、避免竞态条件的场景。与unlimited相对serial是并发度的下限节点并发度参数的有效取值范围正是1 到unlimited之间的任意std::size_t数值serial对应其中的最小值 1。从“有限”到“无限”的取值区间预定义常量只是并发控制体系的锚点除这两个预定义值外用户可以直接传入任意std::size_t数值来限定并发度为 1 到unlimited之间的某个具体上限例如using namespace oneapi::tbb; using namespace oneapi::tbb::flow; // 最多 4 个节点体调用同时执行 function_nodeint, int limited_node(g, 4, [](int v) { return v * 2; }); // 完全串行 function_nodeint, int serial_node(g, serial, [](int v) { return v * 2; }); // 无限制并发 function_nodeint, int parallel_node(g, unlimited, [](int v) { return v * 2; });并发度参数直接影响节点的吞吐量与资源占用数值越小节点体之间的互相排斥越强越接近串行语义数值越大并行度越高但共享状态的竞争风险也相应上升。与节点策略Policy的协同并发限制只回答“同一时刻能跑多少个节点体”而“超限的消息如何处理”由节点的Policy模板参数决定详见 functional_node_policies.rstqueueing默认无法立即处理的消息会先保存在节点内部队列中等并发度允许时再处理rejecting无法立即处理的消息不被节点接受由前驱节点负责处理如重试或转发给其它节点lightweight/queueing_lightweight/rejecting_lightweight在对应策略基础上附加“节点体执行时间很短”的提示帮助实现降低任务调度开销节点体operator()需为noexcept才生效。function_node的try_put行为正好体现了二者的结合“如果并发限制允许就在输入消息上执行用户提供的节点体否则根据节点策略将输入消息排队或拒绝”见 func_node_cls.rst。源码级实现原理常量定义与对外暴露在 include/oneapi/tbb/flow_graph.h 中tbb::detail::d2命名空间内以枚举定义了基础并发级别//! An enumeration the provides the two most common concurrency levels: unlimited and serial enum concurrency { unlimited 0, serial 1 };随后通过using声明在tbb::flow命名空间中公开这两个名字见 include/oneapi/tbb/flow_graph.h使用户代码可以直接书写tbb::flow::unlimited与tbb::flow::serial。节点内部的并发记账机制真正约束节点并发的是 include/oneapi/tbb/detail/_flow_graph_node_impl.h 中function_input_base类的实现。该类持有两个关键成员const size_t my_max_concurrency;构造时传入的并发上限即unlimited、serial或用户自定义数值size_t my_concurrency;当前正在执行的节点体调用计数运行期动态增减。节点通过“占用occupy—释放release”的方式管理并发额度消息到达时尝试占用并发额度if (my_concurrency my_max_concurrency)则my_concurrency节点体调用结束时再递减计数--my_concurrency。因此当my_max_concurrency serial 1时只有第一个到达的消息能成功占用额度其余消息必须等待或按策略排队/拒绝从而保证节点体严格串行当my_max_concurrency unlimited 0时从源码结构看if (my_max_concurrency 0)的相关分支节点在并发计数上不做限制性判断任何消息都可以立即进入节点体从而实现无限制并发。这种“最大并发计数 当前并发计数”的模式同样被multifunction_node的multifunction_input基类复用见 include/oneapi/tbb/detail/_flow_graph_node_impl.h体现了预定义并发限制在多个功能节点间的一致语义。补充资源受限节点与并发限制仓库中还提供了预览特性“资源受限流图”__TBB_PREVIEW_FLOW_GRAPH_RESOURCE_LIMITING见 include/oneapi/tbb/flow_graph.h其中注释明确提到“仅在启用限制即非unlimited时才释放并发额度”见 include/oneapi/tbb/detail/_flow_graph_resource_limiting.h进一步印证unlimited表示“不施加并发约束”而任何有限并发值包括serial都会触发真正的并发额度管理。该预览特性细节可参考 resource_limiting.rst。实战示例下面是一个完整的可编译示例演示unlimited与serial在同一图中的典型用法生产者将数据广播给一个串行节点如写入日志与一个无限制并发节点如并行计算随后汇入后继节点。#include oneapi/tbb/flow_graph.h #include iostream using namespace oneapi::tbb; using namespace oneapi::tbb::flow; int main() { graph g; // 无限制并发任意数量调用可同时执行 function_nodeint, int compute(g, unlimited, [](int v) { return v * v; }); // 串行并发同一时刻仅一个调用执行适合保护共享状态 function_nodeint, void logger(g, serial, [](int v) { std::cout compute v std::endl; }); // 自定义有限并发最多 4 个调用并行 function_nodeint, int worker(g, 4, [](int v) { return v 1; }); make_edge(worker, compute); make_edge(compute, logger); for (int i 0; i 100; i) { worker.try_put(i); } g.wait_for_all(); return 0; }选择建议节点体无共享状态、追求吞吐量 → 使用unlimited节点体有共享状态或必须保序→ 使用serial需要限制资源占用如限流外部调用→ 使用介于serial与unlimited之间的有限数值如4、8并结合queueing或rejecting策略控制超限消息行为。关键要点回顾tbb::flow::unlimited与tbb::flow::serial定义于oneapi/tbb/flow_graph.h是function_node、multifunction_node、async_node构造函数的预定义并发限制参数。unlimited允许任意数量的节点体调用并发执行serial只允许单个调用并发执行二者语义由内部枚举concurrency { unlimited 0, serial 1 }实现并经由tbb::flow命名空间公开。除预定义常量外可传入任意std::size_t数值将并发上限限制在 1 到unlimited之间。并发限制的底层由 include/oneapi/tbb/detail/_flow_graph_node_impl.h 中my_max_concurrency与my_concurrency的占用/释放记账机制保证。并发限制决定“能否立即执行”节点Policy决定“不能立即执行时消息去向”两者共同决定节点的实时行为。赞分享并发编程高性能计算【免费下载链接】oneTBBoneAPI Threading Building Blocks (oneTBB)项目地址https://gitcode.com/gh_mirrors/on/oneTBB点击查看免费下载相关推荐ChatGPT Shortcut 浏览器扩展使用指南侧边栏、显示模式与 AltShiftS 快捷键ChatGPT Shortcut 浏览器扩展使用指南侧边栏、显示模式与 AltShiftS 快捷键 导读 本文基于 ChatGPT ShortcutAAI 应用提示工程人工智能前端Awesome MLOps中的机器学习平台对比AWS SageMaker与Google AI Platform的终极指南Awesome MLOps中的机器学习平台对比AWS SageMaker与Google AI Platform的终极指南 在当今快速发展的机器学习领域选择合文档知识库oneTBB 流图资源消耗控制完全指南limiter_node、并发限制、令牌机制与任务竞技场绑定oneTBB 流图资源消耗控制完全指南limiter_node、并发限制、令牌机制与任务竞技场绑定 在 oneAPI Threading Building B并发编程高性能计算上一篇如何免费提升百度网盘下载速度macOS用户的完整解决方案下一篇5分钟快速上手通达信缠论可视化分析插件终极指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进