ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

mold 链接器中的 oneTBB:任务并行编程入门与项目集成实战指南

mold 链接器中的 oneTBB:任务并行编程入门与项目集成实战指南 mold 链接器中的 oneTBB任务并行编程入门与项目集成实战指南【免费下载链接】moldmold: A Modern Linker 项目地址: https://gitcode.com/GitHub_Trending/mo/moldmold 是一个现代的、以速度为设计目标的高性能链接器其内部大量依赖 oneTBBoneAPI Threading Building Blocks作为并行化引擎。本指南以 oneTBB 官方《Get Started Guide》为骨架结合 mold 仓库中真实的三方库集成与源码用法系统讲解 oneTBB 的任务并行模型、从零到一的可运行示例、环境变量与混合 CPU/NUMA 支持以及通过 CMake* 与 pkg-config 将 oneTBB 集成进自己项目的方法。读完本文你将掌握 oneTBB 的核心并行原语并能独立完成 oneTBB 的安装、编译、运行与项目集成。oneTBB 是什么基于任务的并行编程模型oneTBB 是一个面向 C 代码、基于任务的运行时并行编程模型。它的核心思想是你不必关心线程如何创建与销毁只需要把计算分解成并行运行的任务task运行时负责把任务映射到线程thread上执行。线程是操作系统提供的一种机制允许同一组或不同组的指令同时执行从而让程序运行得更快、更高效。上图展示的正是多个线程并行执行各自任务序列的典型形态——每个线程内部的任务顺序执行不同线程上的任务则并行推进。oneTBB 鼓励开发者写出具有如下特征的代码指定逻辑上的并行结构而非直接操作线程把并行意图交给库而不是手动管理std::thread强调数据并行编程以parallel_for、parallel_reduce等数据驱动算法为主充分利用并发容器与并行算法如concurrent_hash_map、concurrent_vector等线程安全容器以及parallel_sort、parallel_scan等算法库。oneTBB 支持嵌套并行nested parallelism与负载均衡load balancing。这意味着你可以放心地在任务内部再派生子任务而无需担心过度订阅oversubscription——即分配给系统的任务数超过系统能高效处理的上限。这种特性让 oneTBB 在科学计算模拟、游戏、数据分析等对并行度要求高的领域被广泛使用它既可以作为独立产品使用也是 Intel oneAPI 工具套件的组成部分。mold 中的 oneTBB一个真实的并行链接器案例mold 正是 oneTBB 能力的典型受益者。在 mold 的源码中oneTBB 的各类并行原语几乎贯穿了链接的每个阶段例如src/main.cc 用tbb::parallel_for_each(jobs, ...)配合tbb::feeder并行读取输入文件并用 tbb::parallel_sort 对输入文件排序src/main.cc 通过tbb::global_control::max_allowed_parallelism查询/限制全局并行度src/main.cc 用tbb::task_arena与tbb::task_group实现后台低优先级任务src/gc-sections.cc 使用tbb::concurrent_unordered_map与tbb::concurrent_vector构建未使用段回收的根集合src/icf.cc 用tbb::enumerable_thread_specific做线程本地统计用tbb::parallel_sort排序段src/gdb-index.cc 用tbb::parallel_scantbb::blocked_range实现 GDB 索引的并行扫描src/mapfile.cc 用tbb::concurrent_hash_map建立映射表。换句话说理解了本文的入门内容你就能看懂 mold 这样的大型 C 项目是如何利用 oneTBB 榨干多核性能的。开始使用 oneTBB 的五个步骤按照官方《Get Started Guide》开始使用 oneTBB 只需依次完成以下五步查看系统要求System Requirements安装oneTBBInstall oneTBB按照下一步章节的指引运行你的第一个 oneTBB 程序Next Steps学习如何通过CMake* 与 pkg-config将 oneTBB 集成进自己的项目Integrate浏览oneTBB 示例Samples继续深入。下面逐节展开。系统要求与安装oneTBB 支持广泛的硬件平台、操作系统与编译器组合x86/x64、ARM 等架构以及 Linux*、Windows* 等主流操作系统均可与主流 C 编译器配合使用。在动手之前建议先确认目标平台满足官方列出的系统要求。安装方面官方提供了详细的安装说明最通用的两种方式为下载/使用发行包把 oneTBB 安装到install_dir后续通过安装目录下的脚本设置环境变量见下一节源码构建直接以源码方式编译链接到你的工程。在 mold 仓库中可以看到第二种方式的完整落地由于 mold 强制依赖 TBBOneTBB 或 Intel TBB其构建脚本默认直接以源码方式引入本仓库内置的 third-party/tbb 作为三方依赖见 CMakeLists.txt。其中关键配置包括MOLD_USE_SYSTEM_TBB选项默认OFF设为ON时改为链接系统自带的 TBB内置构建时关闭共享库与测试set(BUILD_SHARED_LIBS OFF)、set(TBB_TEST OFF)关闭 TBB 严格模式并禁用动态加载set(TBB_STRICT OFF)、target_compile_definitions(tbb PRIVATE __TBB_DYNAMIC_LOAD_ENABLED0)最终通过find_package(TBB REQUIRED)与target_link_libraries(mold PRIVATE TBB::tbb)完成链接。这一配置恰好就是下文CMake 集成章节的一个生产级范例。下一步设置环境变量并运行第一个程序安装完成后还需要两步才能正式开工。设置环境变量进入 oneTBB 安装目录通过安装目录下的脚本设置环境变量Linux* 系统运行install_dir/tbb/latest/env下的vars.shbash或vars.cshcshWindows* 系统运行install_dir/tbb/latest/env下的vars.bat。提示当进程内同时使用 oneTBB 与 Intel(R) OpenMP 时oneTBB 可以与 OpenMP 协调 CPU 资源的使用避免两者叠加导致过度订阅。如需启用该特性将环境变量TCM_ENABLE设置为1即可。构建并运行一个示例下面是一个最典型的 oneTBB 算法示例计算从 1 到 100 所有整数的和。它使用oneapi::tbb::parallel_reduce将区间1, 101)拆分成若干块并行累加最后再合并各块的部分和。#include oneapi/tbb.h int main() { int sum oneapi::tbb::parallel_reduce( oneapi::tbb::blocked_rangeint(1, 101), 0, [ - int { for (int v r.begin(); v ! r.end(); v) { init v; } return init; }, [](int lhs, int rhs) - int { return lhs rhs; } ); printf(Sum: %d\n, sum); return 0; }在 Linux* 上编译运行g -stdc11 example.cpp -o example -ltbb ./example如果 oneTBB 配置正确输出应为Sum: 5050在 Windows*以 Visual Studio* Code 为例上构建运行在 IDE 中新建一个 C 工程创建example.cpp并粘贴上面的代码打开工程.vscode目录下的tasks.json在args数组中补充两项参数-Ipath/to/oneTBB/include添加 oneTBB 头文件搜索目录path/to/oneTBB/添加 oneTBB 库路径。例如{ tasks: [ { label: build run, type: cppbuild, group: { args: [ /IC:\\Program Files (x86)\\Intel\\oneAPI\\tbb\\2022.0.0\\include, C:\\Program Files (x86)\\Intel\\oneAPI\\tbb\\2022.0.0\\lib\\tbb12.lib ] } ] }构建并运行示例配置正确时输出同样为Sum: 5050。值得一提的细节是blocked_rangeint(1, 101)中的第二个参数是不包含的类似 C 的迭代器区间因此区间实际覆盖 1..100最终累加结果恰为 5050。这种先拆分、后归并的 reduce 模式在 mold 中同样有直接对应——例如 src/gdb-index.cc 用tbb::parallel_scan对条目做并行前缀扫描其参数结构blocked_range 初始值 扫描体 合并体与上面的示例如出一辙。混合 CPU 与 NUMA 支持为了在混合 CPU大小核异构与NUMA非一致内存访问平台上获得最佳性能oneTBB 依赖 HWLOC*硬件拓扑库来感知处理器拓扑。HWLOC 的功能通过一组以tbbbind前缀命名的代理库对外提供oneTBB 会在运行时按需自动加载它们。要保证这些库能被成功找到并加载需要把它们放在与 oneTBB 库本身相同的目录下例如与libtbb.so或tbb.dll同目录。关于 tbbbind 版本有以下几点需要了解从oneTBB 2022.2开始默认的tbbbind库与 HWLOC 2.x静态链接当系统找不到自带 HWLOC 时就会使用这个默认版本如果你希望使用系统自带或自行编译的 HWLOC请确保它出现在动态加载器的搜索路径中Linux* 上通常是LD_LIBRARY_PATHWindows* 上通常是PATH具体请查阅所在平台的动态加载器文档若要指定特定 HWLOC 版本可在 oneTBB 库同目录放置以下 tbbbind 变体tbbbind_2_5依赖 HWLOC2.5 及以上版本需要混合 CPU 支持时使用此版本tbbbind_2_0依赖 HWLOC2.1 ~ 2.4版本。提示如需在运行时确认 tbbbind 是否成功加载可在启动程序前设置环境变量TBB_VERSION1程序会在输出中打印版本与拓扑信息。将 oneTBB 集成进你的项目当你的应用需要并行处理大量数据、希望提升性能与可扩展性时就该把 oneTBB 集成进工程。集成本质上只有两件事链接 oneTBB、提供正确的编译与链接参数。手工配置容易出错因此官方推荐使用 CMake* 与 pkg-config 这两个工具来简化依赖管理。使用 CMake* 集成CMake* 是跨平台构建工具用它集成 oneTBB 可以简化库的构建与链接、保证项目可在多平台构建运行、方便管理依赖。只需在工程的CMakeLists.txt中加入两行find_package(TBB REQUIRED) target_link_libraries(my_executable TBB::tbb)然后像往常一样用 CMake 配置工程即可。mold 的构建脚本就是这套用法的现实投影它通过find_package(TBB REQUIRED)查找系统或内置TBB再以target_link_libraries(mold PRIVATE TBB::tbb)链接完整流程见 CMakeLists.txt。注意官方推荐使用TBB::tbb这个带命名空间的导入目标它会把头文件路径、库路径、链接参数等一并带给你比手工写-I/-L更不容易出错。使用 pkg-config 编译程序pkg-config 通过读取专门的元数据文件来提供包信息从而简化编译命令行、避免在编译脚本里写死大段路径让编译更具可移植性。在 Linux* 上编译测试程序test.cpp可以这样写g -o test test.cpp $(pkg-config --libs --cflags tbb)其中--cflags提供 oneTBB 的头文件搜索路径例如$ pkg-config --cflags tbb -Ipath-to/tbb/latest/lib/pkgconfig/../../include--libs提供 oneTBB 库名及其搜索路径例如$ pkg-config --libs tbb -Lpath-to/tbb/latest/lib/pkgconfig/../../lib/intel64/gcc4.8 -ltbb注意在 Windows* 上还需要额外附加--msvc-syntax选项它会把编译与链接参数转换成 MSVC 兼容的形式。oneTBB 示例从入门到精通的路线图官方提供了覆盖各功能面的示例程序是进阶学习的最佳素材。理解它们有助于正确使用 oneTBB 的特性、避免常见的性能陷阱。示例主要分为以下几类容器Containersconcurrent_hash_map并发哈希映射mold 在 src/mapfile.cc 中即用它构建映射表concurrent_priority_queue并发优先队列。流图Flow Graphbinpack用queue_node、buffer_node与function_node解决装箱问题的示例choleskyCholesky 分解算法dining_philosophers使用带预留reservingjoin_node实现哲学家就餐问题fgbzip2bzip2 块排序文件压缩器的并行实现logic_sim可组合成更大电路的数字逻辑门集合som利用取消cancellation实现的 Kohonen 自组织映射tbb-async-sycl将计算内核拆分到 CPU 与 GPU 上执行。算法Algorithmsparallel_for系列包括生命游戏覆盖game_of_life、多边形覆盖polygon_overlay、并行地震波模拟seismic、并行 2D 光线追踪器tachyon、最大匹配子串查找getting_started、CPU/GPU 可恢复任务tbb-resumable-tasks-syclparallel_for_each对容器元素并行遍历parallel_pipeline流水线并行parallel_reduce并行归约——本文第一个示例即属于此类mold 在 src/input-files.cc 等处的并行处理也可归入此模式。任务调度器Task Schedulertask_arena任务竞技场mold 在 src/main.cc 中用它把 GDB 索引任务限制在低优先级竞技场中执行task_group任务组用于组织一组可等待的任务tbb-task-sycl一个任务执行 SYCL* 代码、另一个任务执行 oneTBB 代码。其他Othertest_all用不同方式计算斐波那契数列对比各种并行实现。小结从任务映射线程的编程模型到可编译运行的parallel_reduce求和示例再到环境变量、混合 CPU/NUMA 支持与 CMake/pkg-config 集成oneTBB 的入门路径清晰而平滑。如果你希望看到这些 API 在高性能场景下的实战形态mold 仓库是最佳参考它用parallel_for_each并行读取输入文件、用concurrent_*容器构建并行数据结构、用task_arena/global_control精细控制并行度与资源——几乎本文提到的每个概念都能在 src 目录下找到对应的生产级代码。【免费下载链接】moldmold: A Modern Linker 项目地址: https://gitcode.com/GitHub_Trending/mo/mold创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表