
并发编程高性能计算【免费下载链接】oneTBBoneAPI Threading Building Blocks (oneTBB)项目地址https://gitcode.com/gh_mirrors/on/oneTBB点击查看免费下载导读tbb-async-sycl是 oneTBBoneAPI Threading Building Blocks官方示例中最能体现异构CPU GPU协同计算编程范式的代码它将一个计算任务按比例拆分为两部分GPU 部分通过 oneTBB Flow Graph 的async_node异步节点调用 SYCL* 内核完成CPU 部分则由function_node功能节点配合tbb::parallel_for完成最后由join_node汇合两路结果并做正确性校验。读完本文你将掌握async_node的 Gateway 机制reserve_wait/release_wait/try_put、CPU/GPU 工作拆分比例的设置方法以及如何用 CMake Intel oneAPI DPC/C 编译器完整构建、运行和验证这类异构应用。示例概述与优化目标tbb-async-sycl示例位于仓库 examples/sycl/tbb-async-sycl它与同目录下的 tbb-task-sycl、tbb-resumable-tasks-sycl 一起构成了 oneTBB 与 SYCL 协作的三种典型范式可参考 examples/sycl/README.md 的对照表Code sample nameSupported Architecture(s)Descriptiontbb-async-syclGPU, CPU计算在 TBB Flow Graph 异步节点调用 GPU 上的 SYCL* 内核与 TBB 功能节点执行 CPU 侧计算之间拆分tbb-task-syclGPU, CPU一个 TBB 任务在 GPU 上执行 SYCL* 代码另一个 TBB 任务使用 TBB parallel_for 执行计算tbb-resumable-tasks-syclGPU, CPU计算在 TBB 可恢复任务在 GPU 上调用 SYCL 内核与 TBB parallel_forCPU 部分之间拆分本示例的官方推荐运行环境如下Optimized forDescriptionOSLinux* Ubuntu* 18.04、Windows* 10/11HardwareSkylake 及更新的处理器配 GEN9 或更新的集成显卡SoftwareIntel® oneAPI DPC/C CompilerWhat you will learn使用 Intel® oneAPI DPC/C 编译器将计算卸载offload到 GPUTime to complete约 15 分钟示例的核心目的是演示在一次执行过程中计算内核如何在 CPU 与 GPU 之间按比例拆分。GPU 侧由 Flow Graph 异步节点负责CPU 侧由功能节点负责两者并行推进最后在图中汇合从而让读者直观理解 oneTBB Flow Graph 与 SYCL 兼容 C 的协作实现即 README 中所说的 Key Implementation Details。源码级全景一张图看懂 CPU/GPU 如何协同示例主程序位于 examples/sycl/tbb-async-sycl/src/tbb-async-sycl.cpp。它完成的是一个经典的triad 向量运算c[i] a[i] alpha * b[i]数组长度array_size 16按ratio 0.5的比例将前一半交给 GPU、后一半交给 CPU。关键常量与数据结构const float ratio 0.5; // CPU 与 GPU 的卸载比例offload ratio const float alpha 0.5; // triad 计算的系数 const size_t array_size 16; std::arrayfloat, array_size a_array; // 输入 std::arrayfloat, array_size b_array; // 输入 std::arrayfloat, array_size c_array; // 输出a_array与b_array通过std::iota初始化为0,1,2,...,15见 tbb-async-sycl.cpp。ratio同时被 CPU 节点与 GPU 异步节点读取是工作拆分的唯一控制点。Flow Graph 拓扑main()中构建的图共有 5 类节点tbb-async-sycl.cppin_node ──┬── cpu_node ──┐ │ ├── join_node ── out_node └── a_node ────┘input_nodefloatin_node只发射一次消息携带ratio值然后通过fc.stop()停止L123-L129。它同时向 CPU 节点和异步节点广播同一个消息。function_nodefloat, done_tagcpu_nodetbb::flow::unlimited并发度。收到offload_ratio后用std::ceil(array_size * offload_ratio)计算 CPU 段的起始下标再用tbb::parallel_for配合tbb::blocked_rangesize_t处理后半段L132-L148。async_nodefloat, done_taga_nodeGPU 侧入口构造时传入AsyncActivity的submit调用L151-L156。join_nodestd::tupledone_tag, done_tag, queueingnode_join等 CPU 与 GPU 两路都完成任务后才放行L159-L160。function_nodejoin_t::output_typeout_node串行地计算黄金版本c_gold与异构计算得到的c_array逐元素比对输出校验结论L163-L181。done_tag是一个空结构体仅作为任务完成的信号tbb-async-sycl.cpp这正是 Flow Graph 消息驱动模型的典型用法消息本身不一定携带数据也可以只携带事件已发生的语义。线程调度约束int nth 4; // number of threads auto mp tbb::global_control::max_allowed_parallelism; tbb::global_control gc(mp, nth 1); // 多留一个线程但它处于休眠状态见 tbb-async-sycl.cpp。这里通过tbb::global_control把最大并行度设为nth 1多出的那个线程会被AsyncActivity内部的service_thread占用该线程在submit_flag置位前一直yield等待其余 4 个线程供给 Flow Graph 与parallel_for使用。深入 async_nodeGateway 机制是异构协作的关键async_node之所以能对接外部异步活动本例中是 SYCL 队列 独立服务线程依赖其Gateway协议。相关实现位于 include/oneapi/tbb/flow_graph.h。Gateway 的三个核心调用在示例中using async_node_type tbb::flow::async_nodefloat, done_tag; using gateway_type async_node_type::gateway_type;gateway_type就是receiver_gatewayoutput_typeflow_graph.h。异步活动通过它向 Flow Graph 报告生命周期gateway.reserve_wait()异步活动开始前调用通知图有一个外部任务正在执行图据此增加等待计数。在示例的AsyncActivity::submit中首先执行tbb-async-sycl.cpp。gateway.try_put(output)外部活动完成后把输出消息投递回 Flow Graph。示例中 SYCL 块执行完毕后调用gateway_ptr-try_put(done_tag{})L95。从源码看try_put最终进入try_put_impl通过gather_successful_try_puts将消息分发给后继端口并把任务入队到图的 arena 中flow_graph.h。gateway.release_wait()异步活动结束递减等待计数配合reserve_wait保证graph.wait_for_all()不会在外部活动真正完成前返回L96。对应实现见 flow_graph.h它同时会调用fgt_async_commit记录 ITT 分析事件。AsyncActivity将 SYCL 工作打包成外部活动AsyncActivity类tbb-async-sycl.cpp封装了完整的异步生命周期构造函数中启动一个service_thread线程在submit_flag被置位前自旋等待置位后执行 SYCL 卸载逻辑。submit(ratio, gateway)由async_node的 body 调用async_act.submit(offload_ratio, gateway)它先reserve_wait()保存 gateway 指针与比例再置位submit_flag唤醒服务线程。析构函数service_thread.join()保证退出时异步线程已结束。这种异步节点 body 只做提交submit、真正的异步工作由独立线程完成的模式正是async_node与普通function_node的本质区别function_node 的 body 在 Flow Graph 的执行线程上同步运行而 async_node 允许工作发生在图之外的任意线程/设备上再通过 Gateway 把结果送回图中。SYCL 内核的编写与同步语义异步线程内执行的 GPU 计算tbb-async-sycl.cppsize_t array_size_sycl std::ceil(array_size * offload_ratio); const float coeff alpha; // coeff 为局部变量供内核捕获 { // 将 SYCL 工作放入一个块作用域内 sycl::range1 n_items{ array_size_sycl }; sycl::buffer a_buffer(a_array); sycl::buffer b_buffer(b_array); sycl::buffer c_buffer(c_array); sycl::queue q(sycl::default_selector_v, dpc_common::exception_handler); q.submit( { sycl::accessor a_accessor(a_buffer, h, sycl::read_only); sycl::accessor b_accessor(b_buffer, h, sycl::read_only); sycl::accessor c_accessor(c_buffer, h, sycl::write_only); h.parallel_for(n_items, { c_accessor[index] a_accessor[index] b_accessor[index] * coeff; }); }).wait(); }这里有三个值得注意的工程细节块作用域即同步屏障源码注释明确指出——把 SYCL 工作全部放入{}块内确保块退出前所有排队的 SYCL 任务全部完成。这是因为sycl::buffer的析构写回主机内存发生在块结束时配合末尾的.wait()双重保障。CPU/GPU 边界对齐GPU 处理[0, ceil(16*0.5)) [0, 8)CPU 处理[8, 16)由std::ceil(array_size * offload_ratio)计算的i_start决定见 L136-L137。输出日志start index for GPU 0; end index for GPU 8与start index for CPU 8; end index for CPU 16正是这一拆分的直观呈现。dpc_common::exception_handler来自 oneAPI dev-utilities 的dpc_common.hpp源码注释指出其位于$ONEAPI_ROOT/dev-utilities/include/dpc_common.hpp用于统一捕获 SYCL 异步异常保证出错时给出可读的诊断信息而不是静默失败。构建与运行从零到make run设置 oneAPI 环境变量使用命令行接口CLI开发前必须先通过setvars脚本配置 Intel® oneAPI Toolkit 环境每次新开终端都需重新 source以确保编译器、库和工具就绪Linux*系统级安装. /opt/intel/oneapi/setvars.shLinux*私有安装. ~/intel/oneapi/setvars.sh非 POSIX shell如 csh$ bash -c source install-dir/setvars.sh ; exec cshWindows*C:\Program Files (x86)\Intel\oneAPI\setvars.batWindows PowerShell*cmd.exe /K C:\Program Files (x86)\Intel\oneAPI\setvars.bat powershellMicrosoft Visual Studio*在命令提示符中执行setx SETVARS_CONFIG 只需设置一次此后每次启动 Visual Studio 都会自动执行setvars脚本此外官方还提供两类可选的环境配置方式Modulefiles 脚本适用于所有 Linux shell与setvars 配置文件可精确指定组件列表及版本。关于环境变量与 setvars 的详细用法可查阅 Intel oneAPI 编程指南中 Use the setvars Script 与 Use Modulefiles with Linux 相关章节。可选使用 Visual Studio Code借助 VS Code 扩展可以简化环境配置、launch 配置与示例下载使用扩展Code Sample Browser for Intel® Software Development Tools下载示例使用扩展Environment Configurator for Intel® Software Development Tools配置 oneAPI 环境在 VS Code 中打开终端Terminal New Terminal按下文命令行说明在终端中运行示例仅 Linux使用Generate Launch Configurations扩展生成配置配合 GDB for Intel® oneAPI Toolkits 调试 GPU 应用。Linux 构建、运行与清理cd tbb-async-sycl mkdir build cd build cmake .. make VERBOSE1make runmake clean其中make run是构建系统预置的自定义目标在 src/CMakeLists.txt 中通过add_custom_target(run ./tbb-async-sycl)定义等价于直接执行生成的可执行文件。CMake 配置要点顶层 CMakeLists.txt 揭示了编译器与链接的关键配置WindowsCMAKE_CXX_COMPILER设为icx-cl编译与链接均追加-fsycl另加/EHsc开启异常处理Linux/macOSCMAKE_CXX_COMPILER设为icpx编译与链接追加-fsycl子目录 src/CMakeLists.txt 通过-qtbbWindows 下为/Qtbb链接 oneTBB并find_package(Threads REQUIRED)链接Threads::Threads因为示例显式创建了std::thread未显式指定CMAKE_BUILD_TYPE时默认使用RelWithDebInfoRelease 附带调试信息。运行结果解读与正确性校验构建并运行后预期输出如下start index for GPU 0; end index for GPU 8 start index for CPU 8; end index for CPU 16 Heterogeneous triad correct. c_array: 0 1.5 3 4.5 6 7.5 9 10.5 12 13.5 15 16.5 18 19.5 21 22.5 c_gold : 0 1.5 3 4.5 6 7.5 9 10.5 12 13.5 15 16.5 18 19.5 21 22.5 Built target run输出解读前两行确认工作拆分正确GPU 处理[0,8)CPU 处理[8,16)Heterogeneous triad correct.表示异构结果与黄金参考完全一致——out_node中用串行循环计算c_gold再通过std::equal与c_array比对tbb-async-sycl.cpp。若不一致会输出Heterogeneous triad error.两行数值完全相同验证了 CPU 与 GPU 两条路径对同一公式c a alpha*b的计算结果一致其中c[0]00.5*00、c[1]10.5*11.5、…、c[15]150.5*1522.5。如果运行出错可借助Diagnostics Utility for oneAPI进行故障排查详见 Intel oneAPI 诊断工具用户指南。从示例到实战参数调节与扩展方向调节卸载比例修改ratio如0.25、0.75即可改变 GPU/CPU 的工作量分配日志中的起止下标会随之变化。实际项目中应依据设备负载与数据迁移成本选择比例。替换计算内核h.parallel_for中的 lambda 即 SYCL 内核可替换为任意设备端计算注意coeff以值捕获进内核避免引用悬垂。对接更大数据规模array_size为编译期常量std::array如需动态规模可改用sycl::buffer包裹动态分配的主机内存并相应调整blocked_range的区间划分。理解async_node的适用场景从 flow_graph.h 的构造函数可以看出async_node(graph, concurrency, body, policy)要求 body 形如(input, gateway_type) - void凡是需要把工作交给图外部线程或设备GPU、远程节点、异步 I/O 等再回收结果的场景都适合采用async_node Gateway 协议而不是用function_node阻塞等待。对照 examples/sycl/README.md 可知若不想引入async_node的 Gateway 复杂度还可以改用tbb-task-syclTBB 任务直调 SYCL或tbb-resumable-tasks-sycl可恢复任务两种思路——三者覆盖了 oneTBB 与 SYCL 协作的主要编程模型tbb-async-sycl是理解 Flow Graph 异步集成机制的绝佳起点。赞分享并发编程高性能计算【免费下载链接】oneTBBoneAPI Threading Building Blocks (oneTBB)项目地址https://gitcode.com/gh_mirrors/on/oneTBB点击查看免费下载相关推荐如何用VideoSrt解决视频字幕制作难题从零到精通的完整指南如何用VideoSrt解决视频字幕制作难题从零到精通的完整指南 还在为视频字幕制作而烦恼吗传统的字幕制作流程繁琐耗时需要反复听写、校对、时间轴对齐一个1开发工具构建工具系统编程突破性能极限如何利用oneTBB与SYCL实现异构计算革命突破性能极限如何利用oneTBB与SYCL实现异构计算革命 oneAPI Threading Building Blocks oneTBB 是一款强大的并行编并发编程高性能计算oneTBB Flow Graph 实战解析examples/graph 六大官方图计算示例oneTBB Flow Graph 实战解析examples/graph 六大官方图计算示例 导读 oneAPI Threading Building Blo并发编程高性能计算上一篇ZKP-HMAC API完全手册ZeroKnowledge类核心方法详解下一篇在 macOS 上使用 Python pymssql 连接 Azure SQL Database 实战指南基于 sql-server-samples 示例解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考