新闻详情

新闻详情

首页 / 资讯中心 / 详情

mold 项目中的 oneTBB 可扩展内存分配器(tbbmalloc):scalable_allocator、cache_aligned_allocator 与 malloc 自动替换实践

发布时间:2026/9/15 15:31:23来源:尧图网络
mold 项目中的 oneTBB 可扩展内存分配器(tbbmalloc):scalable_allocator、cache_aligned_allocator 与 malloc 自动替换实践
mold 项目中的 oneTBB 可扩展内存分配器tbbmallocscalable_allocator、cache_aligned_allocator 与 malloc 自动替换实践【免费下载链接】moldmold: A Modern Linker 项目地址: https://gitcode.com/GitHub_Trending/mo/mold本篇技术指南以 mold 仓库内 vendored 的 oneTBB 官方文档 Scalable_Memory_Allocator.rst 为核心骨架系统讲解 oneTBB 可扩展内存分配器tbbmalloc的库结构、分配器模板、C 接口、运行期配置与 malloc 自动替换方案。读完本文你将掌握 tbbmalloc 在 mold 项目中的实际定位、scalable_allocatorT与cache_aligned_allocatorT的选型依据、scalable_allocation_mode/scalable_allocation_command的完整参数语义以及如何在 Linux/Windows 上通过 proxy 库无缝接管 C/C 动态内存分配。背景mold 与 oneTBB 可扩展内存分配器的关系mold 是一个高性能现代链接器其并行实现大量依赖 oneTBBoneAPI Threading Building Blocks。从源码可见mold 在 arch-arm32.cc、arch-x86-64.cc、gc-sections.cc 等核心文件中直接使用tbb::parallel_for、tbb::parallel_for_each、tbb::concurrent_unordered_map、tbb::concurrent_vector并在 cmdline.cc 中使用tbb::global_control控制线程数。oneTBB 被整体 vendored 在仓库的 third-party/tbb 目录下其官方文档、头文件、源码与测试一并保留其中就包括可扩展内存分配器scalable memory allocator的完整文档体系。oneTBB 的 release 与 debug 版本均由两个动态共享库构成一个是提供通用并行支持并行算法、容器、任务调度的库另一个就是可扩展内存分配器库后者以库名中的malloc字样区分。以 Windows 为例release 版对应为tbbversion.dll与tbbmalloc.dll。应用程序可以选择只链接通用库、只链接可扩展内存分配器或者两者都使用详见 Scalable_Memory_Allocator.rst。需要说明的是mold 本体在并行化中主要使用 oneTBB 的通用库组件并行算法与并发容器而本文重点阐述的 tbbmalloc 是同一发行版中可独立选用的内存分配组件——mold 将其随 oneTBB 一并 vendored作为完整的第三方依赖树的一部分。两个分配器模板解决并行编程的两大核心问题oneTBB 提供多个类似 STLstd::allocator的分配器模板其中scalable_allocatorT与cache_aligned_allocatorT分别针对并行编程中两个截然不同的问题详见 Memory_Allocation.rst。可扩展性scalable_allocator问题为串行程序设计的分配器在并发场景下会出现扩展性问题——多线程竞争同一个共享内存池同一时刻只允许一个线程执行分配形成串行化瓶颈。方案使用scalable_allocatorT模板规避扩展性瓶颈。该模板能显著提升频繁分配/释放内存的程序的性能其内部为每个线程维护独立的缓存与缓冲减少全局锁竞争。伪共享cache_aligned_allocator问题当两个线程访问共享同一条缓存行cache line中的不同字时会发生伪共享false sharing。缓存行是处理器缓存间信息交换的单位若一个处理器修改某条缓存行而另一个处理器读取同一条缓存行则整条缓存行必须从一个处理器搬运到另一个处理器——即使两个处理器操作的是行内不同的字。由于缓存行搬运可能耗费数百个时钟周期伪共享会显著损害性能。方案使用cache_aligned_allocatorT模板保证每次分配都对齐到独立的缓存行。由cache_aligned_allocator分配的两个对象之间保证不会发生伪共享但如果一个对象由cache_aligned_allocator分配、另一个对象以其他方式分配则无此保证。这两个分配器模板可直接作为 STL 容器的allocator模板参数使用。例如声明一个使用cache_aligned_allocator分配的std::vectorstd::vectorint, cache_aligned_allocatorint v;使用提示cache_aligned_allocatorT的功能有空间代价——即使是很小的对象它也至少要分配一条缓存行的内存。因此只有当伪共享确实可能成为问题时才应使用它该提示同样记录在 Memory_Allocation.rst 中。库的选型Which Dynamic Libraries to Use不同分配器模板对链接库的要求并不相同。scalable_allocatorT必须依赖可扩展内存分配器库且无需依赖 oneTBB 通用库可独立使用而tbb_allocatorT与cache_aligned_allocatorT在分配器库存在时使用它否则自动回退到malloc/free——因此即使应用选择不链接分配器库这两个模板依然可用详见 Which_Dynamic_Libraries_to_Use.rst。模板库要求说明scalable_allocatorT必须链接 oneTBB 可扩展内存分配器库不要求通用库可独立于 oneTBB 其余部分使用tbb_allocatorT、cache_aligned_allocatorT无强制要求分配器库存在时使用之否则回退到malloc/freeoneTBB 其余组件并行算法、任务调度、容器等无论是否链接分配器库均可正常使用。C 级接口scalable_malloc 函数家族除 C 模板分配器外可扩展内存分配器还提供一组与 C 标准库内存管理例程等价的函数区别仅在于函数名带有scalable_前缀定义于头文件oneapi/tbb/scalable_allocator.h完整声明见 c_interface_to_scalable_allocator.rstextern C { // C 内存分配器的可扩展等价物 void* scalable_malloc( size_t size ); void scalable_free( void* ptr ); void* scalable_calloc( size_t nobj, size_t size ); void* scalable_realloc( void* ptr, size_t size ); // _msize/malloc_size/malloc_usable_size 的等价物 size_t scalable_msize( void* ptr ); // posix_memalign 的可扩展等价物 int scalable_posix_memalign( void** memptr, size_t alignment, size_t size ); // 对齐分配 void* scalable_aligned_malloc( size_t size, size_t alignment); void scalable_aligned_free( void* ptr ); void* scalable_aligned_realloc( void* ptr, size_t size, size_t alignment ); }除scalable_allocation_mode与scalable_allocation_command外每个scalable_x例程的行为都与库函数x类似。这些例程构成两个家族同一家族的分配/释放/调整大小函数必须配对使用由scalable_x函数家族分配的存储必须由同一家族的函数释放或调整大小不得交给 C 标准库函数处理反之由 C 标准库函数分配的存储也不应由scalable_x函数释放或调整大小。分配例程释放例程对应的库函数家族scalable_malloc/scalable_calloc/scalable_reallocscalable_freeC 标准库scalable_posix_memalignscalable_freePOSIXscalable_aligned_malloc/scalable_aligned_reallocscalable_aligned_freeMicrosoft C 运行时库另外两个不执行分配/释放、但可查询信息或影响分配器行为的函数scalable_msize(ptr)若ptr指向由可扩展分配器分配的内存块返回其可用大小若ptr不是这样的块返回 0。scalable_allocation_mode(mode, value)/scalable_allocation_command(cmd, reserved)见下节。状态码方面分配器相关函数以枚举ScalableAllocationResult返回结果TBBMALLOC_OK成功、TBBMALLOC_INVALID_PARAM参数无效、TBBMALLOC_UNSUPPORTED不支持、TBBMALLOC_NO_MEMORY内存不足、TBBMALLOC_NO_EFFECT操作未产生效果。运行期配置分配模式、命令与环境变量scalable_allocation_mode分配模式int scalable_allocation_mode(int mode, intptr_t value)用于调整分配器行为其设置会一直生效直到再次调用改变它。返回TBBMALLOC_OK表示成功若mode不是下述合法值或value对给定模式无效返回TBBMALLOC_INVALID_PARAM。合法模式参数如下参数宏语义TBBMALLOC_USE_HUGE_PAGESscalable_allocation_mode(TBBMALLOC_USE_HUGE_PAGES, 1)指示分配器在操作系统允许时使用大页huge pages传 0 关闭。若平台不支持大页可能返回TBBMALLOC_NO_EFFECT。当前仅 Linux 支持兼容显式配置与透明大页两种模式TBBMALLOC_SET_SOFT_HEAP_LIMITscalable_allocation_mode(TBBMALLOC_SET_SOFT_HEAP_LIMIT, size)设置分配器从操作系统获取内存总量的软阈值字节。超过阈值会促使分配器释放内部缓冲中的内存但不会阻止其在需要时继续申请更多内存TBBMALLOC_SET_HUGE_SIZE_THRESHOLDscalable_allocation_mode(TBBMALLOC_SET_HUGE_SIZE_THRESHOLD, size)设置巨大对象的下界阈值字节无上限。任何大于该阈值的对象都被视为巨大对象不参与内部定期清理逻辑但不影响TBBMALLOC_SET_SOFT_HEAP_LIMIT模式与TBBMALLOC_CLEAN_ALL_BUFFERS操作的逻辑scalable_allocation_command分配器命令int scalable_allocation_command(int cmd, void* reserved)用于命令分配器执行指定动作第二个参数保留、必须传 0否则返回TBBMALLOC_INVALID_PARAM。合法命令如下命令宏语义TBBMALLOC_CLEAN_ALL_BUFFERS清理分配器所有线程的内部内存缓冲可能降低内存占用但可能导致后续分配请求耗时增加。该命令不适合频繁调用建议仔细评估性能影响。注意不保证调用后会释放全部未用内存若无缓冲被释放可能返回TBBMALLOC_NO_EFFECTTBBMALLOC_CLEAN_THREAD_BUFFERS仅清理调用线程的内部内存缓冲若无缓冲被释放可能返回TBBMALLOC_NO_EFFECT环境变量无需改代码即可调优部分分配器参数也可以通过系统环境变量设置便于在不修改应用源码的情况下调整行为、确保设置尽早生效或避免对 oneTBB 分配器二进制文件的显式依赖详见 Allocator_Configuration.rstTBB_MALLOC_USE_HUGE_PAGES控制内存映射是否使用大页。设为 1 的效果等同于scalable_allocation_mode(TBBMALLOC_USE_HUGE_PAGES, 1)。TBB_MALLOC_SET_HUGE_OBJECT_THRESHOLD定义被视为巨大、不参与常规清理操作的对象大小的下界字节。注意文档在环境变量一节写作TBB_MALLOC_SET_HUGE_OBJECT_THRESHOLD而规范文档 c_interface_to_scalable_allocator.rst 中对应的环境变量名为TBB_MALLOC_SET_HUGE_SIZE_THRESHOLD实际以你使用的 oneTBB 版本头文件与发行说明为准该环境变量的取值上限受LONG_MAX限制。优先级规则这些环境变量只在内存管理器初始化时生效之后的修改会被忽略而scalable_allocation_mode的调用覆盖对应环境变量的效果即函数调用优先于环境变量。自动替换 mallocproxy 库方案在 Windows 与 Linux 上可以自动将所有标准动态内存分配函数如malloc的调用替换为 oneTBB 的可扩展等价实现这有时能改善应用性能。替换由proxy 库提供库名见各平台小节且proxy 库与可扩展内存分配器库必须取自同一 oneTBB 发行版否则两者可能互不兼容详见 automatically-replacing-malloc.rst。Linux 下的替换release 版 proxy 库为libtbbmalloc_proxy.sodebug 版为libtbbmalloc_proxy_debug.so。被替换的动态内存函数包括标准 C 库函数malloc、calloc、realloc、free以及 C11 新增的aligned_alloc标准 POSIX 函数posix_memalign已废弃函数valloc、memalign、pvalloc、mallopt可替换的全局 C 运算符new与deleteglibc 特有函数malloc_usable_size、__libc_malloc、__libc_calloc、__libc_memalign、__libc_free、__libc_realloc、__libc_pvalloc、__libc_valloc。两种替换方式详见 Linux_C_Dynamic_Memory_Interface_Replacement.rst# 方式一程序加载时通过 LD_PRELOAD 装载 release 版 proxy 库无需改动可执行文件 LD_PRELOADlibtbbmalloc_proxy.so # 方式二链接主可执行文件时直接链接 proxy 库 g foo.o bar.o -ltbbmalloc_proxy -o a.out使用 debug 版时将上述命令中的tbbmalloc_proxy替换为tbbmalloc_proxy_debug即可。程序加载器必须能在加载时找到 proxy 库与可扩展内存分配器库——可将库所在目录加入LD_LIBRARY_PATH环境变量或加入/etc/ld.so.conf。Linux 替换限制不支持 glibc 内存分配钩子如__malloc_hook不支持 Mono 运行时。Windows 下的替换release 版 proxy 库为tbbmalloc_proxy.dlldebug 版为tbbmalloc_proxy_debug.dll。被替换的函数包括标准 C 库的malloc、calloc、realloc、free可替换的全局new/deleteMicrosoft C 运行时库的_msize、_aligned_malloc、_aligned_realloc、_aligned_free、_aligned_msize。注意不支持对 Universal Windows PlatformUWP应用的替换。两种替换方式详见 Windows_C_Dynamic_Memory_Interface_Replacement.rst// 方式一在应用启动时加载的任一二进制源码中加入头文件 #include oneapi/tbb/tbbmalloc_proxy.h; 方式二在启动时加载的 .exe/.dll 的链接器选项中添加参数 ; 32 位代码注意是三重下划线 tbbmalloc_proxy.lib /INCLUDE:___TBB_malloc_proxy ; 64 位代码注意是双重下划线 tbbmalloc_proxy.lib /INCLUDE:__TBB_malloc_proxy程序加载器须能在加载时找到 proxy 库与分配器库可将库所在目录加入PATH环境变量。Windows 的替换基于对 Visual C 运行时库的内存内二进制插桩in-memory binary instrumentation为保证正确性必须首先识别出这些库中的一部分动态内存函数若出现问题替换会被跳过程序继续使用标准内存分配函数。可用TBB_malloc_replacement_log函数检查替换是否成功并获取附加信息。若要将某次程序调用的替换禁用可将TBB_MALLOC_DISABLE_REPLACEMENT环境变量设为 1但即使禁用程序启动时仍然需要 oneTBB 内存分配库存在。与 mold 项目的对应关系从文档到真实并行代码上述文档体系并非孤立的第三方资料而是 mold 实际依赖的并行基础设施。mold 在链接流程的多个热路径上使用 oneTBB 的并行组件例如gc-sections.cc 使用tbb::concurrent_unordered_map与tbb::concurrent_vector组织段集合sections与根集rootset并用tbb::parallel_for_each并行遍历输入对象文件arch-arm32.cc 与 arch-ppc64v1.cc 等架构后端用tbb::parallel_for/tbb::parallel_for_each并行处理重定位等条目cmdline.cc 通过tbb::global_control设置并行工作线程数量。这正是多线程需要可扩展内存分配、避免分配器串行化瓶颈这一文档核心诉求的真实场景。对于需要自己管理内存分配的模块例如大量小对象并发分配即可按本文介绍的分配器模板与 C 接口进行替换如需全局接管则可参考 proxy 库方案。相关文档与规范的完整体系可在仓库内继续研读Memory_Allocation.rst分配器模板与伪共享详解、Which_Dynamic_Libraries_to_Use.rst库选型表、Allocator_Configuration.rst运行期配置、c_interface_to_scalable_allocator.rstC 接口规范以及 specification/source/memory_allocation.rst内存分配规范总览涵盖std::pmr::memory_resource实现如cache_aligned_resource、scalable_memory_resource。实践要点小结按需选库仅用scalable_allocatorT可只链接分配器库tbb_allocatorT/cache_aligned_allocatorT在无分配器库时自动回退到malloc/free。配对使用scalable_x家族与 C 标准库家族的分配/释放函数不可混用scalable_allocation_command的reserved参数必须为 0。区分两类问题追求多线程分配吞吐用scalable_allocatorT对抗缓存行伪共享用cache_aligned_allocatorT注意其最小按缓存行分配的空间代价。配置优先级scalable_allocation_mode优先于同名环境变量环境变量仅在内存管理器初始化时生效。proxy 替换Linux 用LD_PRELOAD或链接-ltbbmalloc_proxyWindows 用头文件或/INCLUDE链接选项务必保证 proxy 库与分配器库来自同一 oneTBB 发行版。平台限制大页模式目前仅 Linux 支持glibc 的__malloc_hook与 Mono 不受支持Windows 的 UWP 应用不支持替换。【免费下载链接】moldmold: A Modern Linker 项目地址: https://gitcode.com/GitHub_Trending/mo/mold创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Loop 的 8 方向径向菜单:macOS 窗口管理 10 分钟上手 2026/9/15 16:10:31

Loop 的 8 方向径向菜单:macOS 窗口管理 10 分钟上手

Loop 的 8 方向径向菜单:macOS 窗口管理 10 分钟上手 【免费下载链接】Loop Window management made elegant. 项目地址: https://gitcode.com/GitHub_Trending/lo/Loop Loop 是一款 macOS 窗口管理工具,按住一个触发键、朝屏幕任意方向拖一下鼠标…

阅读更多 →
亿图图示实战经验:绘图提效技巧与避坑指南 2026/9/15 16:10:31

亿图图示实战经验:绘图提效技巧与避坑指南

画图这件事,在不少人眼里是“打开软件拖几个框连几根线”,但真正靠画图吃饭的人都知道,工具选不好,一天能浪费半天。我最早画网络拓扑图和技术方案图用的是老牌Visio,功能确实硬,可授权方式和价格对个人用户…

阅读更多 →
知识图谱驱动的用户画像系统建设:从标签宽表到关系推理 2026/9/15 16:10:31

知识图谱驱动的用户画像系统建设:从标签宽表到关系推理

我在前年接手了一个内部用户画像分析子系统建设的项目,第一个月几乎每天都在跟一张几十个字段的标签宽表搏斗。表里写着用户A的性别、年龄、品类偏好、消费等级,但当我问“这个用户为什么会有这个偏好”“跟他行为模式最像的一批人是谁”的时候&#xff…

阅读更多 →
Apache DolphinScheduler Linkis 任务节点实战指南:基于 linkis-cli 的引擎作业提交、状态跟踪与配置详解 2026/9/15 16:10:31

Apache DolphinScheduler Linkis 任务节点实战指南:基于 linkis-cli 的引擎作业提交、状态跟踪与配置详解

Apache DolphinScheduler Linkis 任务节点实战指南:基于 linkis-cli 的引擎作业提交、状态跟踪与配置详解 【免费下载链接】dolphinscheduler Apache DolphinScheduler is the modern data orchestration platform. Agile to create high performance workflow with…

阅读更多 →
PHP原生学生管理系统:权限分层与CSV导入导出实战 2026/9/15 16:10:31

PHP原生学生管理系统:权限分层与CSV导入导出实战

简介:这是一套基于PHP与MySQL开发的学生成绩管理系统源码,面向Web开发初学者及课程设计实践者,帮助理解前后端交互、数据库操作与基础权限管理逻辑。资源共33个文件,包含6个核心PHP脚本(如login.php、database.php&…

阅读更多 →
Apache Thrift Windows 环境搭建与编译器构建完全指南(预编译 EXE / Visual Studio / Cygwin / MinGW) 2026/9/15 16:07:30

Apache Thrift Windows 环境搭建与编译器构建完全指南(预编译 EXE / Visual Studio / Cygwin / MinGW)

Apache Thrift Windows 环境搭建与编译器构建完全指南(预编译 EXE / Visual Studio / Cygwin / MinGW) 【免费下载链接】thrift Apache Thrift 项目地址: https://gitcode.com/GitHub_Trending/thr/thrift 本篇技术指南以 Apache Thrift 官方 Win…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞