资讯动态

CANN Runtime 流序内存池(Stream-Ordered Memory Pool)实战指南:创建、属性配置与异步分配

发布时间:2026/9/18 16:01:16 来源:尧图企业网站定制
CANN Runtime 流序内存池Stream-Ordered Memory Pool实战指南创建、属性配置与异步分配【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime本文围绕 CANN Runtime 中流序内存池Stream-Ordered Memory Pool即 SOMA 机制这一高级内存管理能力展开讲解内存池的创建、属性配置、异步申请/释放以及与常规aclrtMalloc/aclrtFree的适用场景对比。读者将掌握aclrtMemPoolCreate、aclrtMemPoolSetAttr/GetAttr、aclrtMemPoolMallocAsync、aclrtMemPoolFreeAsync和aclrtMemPoolTrimTo一套完整的 API 用法理解内存池阈值、保留内存与已用内存等关键指标的真实含义并能在算子高频下发的场景中直接落地使用。背景为什么需要流序内存池在常规编程模型下设备内存管理依赖同步接口aclrtMalloc与aclrtFree。典型的使用方式是申请内存 → 异步拷贝数据到 Device 侧 → 下发算子任务 →同步 Stream 确认内存使用完毕→ 释放内存。示例代码如下#include acl/acl_rt.h #include acl/acl.h int main() { typedef struct { ...... } ArgsInfo; void *ptr0 nullptr; aclrtStream stream1; // 申请内存 aclrtMalloc(ptr0, sizeof(ArgsInfo), ACL_MEM_MALLOC_HUGE_FIRST); ...... // 配置任务下发 ArgsInfo usrArgs; // 拷贝信息到device侧申请内存 error aclrtMemcpyAsync(ptr0, sizeof(ArgsInfo), (void *)usrArgs, sizeof(ArgsInfo), ACL_MEMCPY_HOST_TO_DEVICE, stream1); // 下发任务 uint32_t blockDim 32; aclrtLaunchKernelV2(funcHandle, blockDim, (void *)usrArgs, sizeof(ArgsInfo), nullptr, stream1); // 流同步以同步释放申请内存 aclrtSynchronizeStream(stream1); // 释放内存释放前需要流同步 aclrtFree(ptr0); ...... // 流同步 aclrtSynchronizeStream(stream1); return 0; }如上代码所示aclrtFree之前必须显式执行aclrtSynchronizeStream来保证内存不再被异步任务使用否则可能产生数据竞争或非法内存访问。在算子下发数量少、内存调整频率低的场景下这种模式是可接受的但面对大量算子下发与高频内存申请/释放的负载时会暴露两个突出问题同步瓶颈任务下发过程中一旦涉及内存分配或释放的调整就不得不引入 Stream 同步打断异步流水拖累整体执行效率。累积延迟内存申请与释放本身耗时频繁操作会累积出可观的额外延迟进一步压缩性能空间。流序内存池Stream-Ordered Memory Pool正是为打破这一瓶颈而设计它把内存的分配与释放动作融入 Stream 的调度序列由 Stream 自身的有序执行机制保证内存操作安全无需显式同步即可进行内存管理同时 Runtime 提供内存复用能力能够全面支撑复杂的内存管理场景。本功能在仓库中的落点见 example/3_memory_advanced/memory_pool/README_en.md关联文档、完整 API 手册见 docs/zh/api_ref/11-10_ordered_stream_memory_allocation.md。流序内存池核心模型一次申请/释放的完整生命周期流序内存池的核心思路是将内存管理任务化。从源码实现看其运行时链路分为三层ACL 封装层src/acl/aclrt_impl/memory.cpp中的aclrtMemPoolCreateImpl等函数完成参数校验、类型映射与运行时调用Runtime API 层src/runtime/api/api_c_soma.cc中的rtMemPoolCreate等 C 接口经ApiSoma分发到ApiImplSoma见 src/runtime/api/impl/api_impl_soma.ccSOMA 内核层真正的内存管理逻辑位于 src/runtime/feature/soma/soma.cc通过SomaApi::AllocFromMemPool/FreeToMemPool与SegmentManager段管理器协同并借助 AICore 侧的SomaMemMng内核以AicpuOpType::MALLOC/FREE任务形式下发到指定 Stream完成异步语义。以异步申请为例ApiImplSoma::MemPoolMallocAsyncapi_impl_soma.cc的执行路径可以概括为校验devPtr、memPoolId、stm及当前 Context/Stream 匹配关系将请求大小按DEVICE_POOL_MIN_BLOCK_SIZE对齐源码中(size alignMask) ~alignMask并做溢出检查通过SomaApi::QueryMemPool定位内存池失败时返回RT_ERROR_MEM_POOL_NULL调用SomaApi::AllocFromMemPool从池中切出内存块得到虚拟地址va通过SomaAicpuKernelLaunch(SomaMemMng, ...)在指定 Stream 上下发 MALLOC 管理任务将该分配动作纳入 Stream 保序序列若下发失败则回滚归还。对应的MemPoolFreeAsync则先通过SomaApi::InMemPoolRegion判断指针是否属于 SOMA 池若是则归还池中并下发 FREE 任务若不是例如指针来自同步分配则退化为注册 Host 回调LaunchHostFuncMemPoolFreeAsyncCallback执行DevFreeStatic。从源码结构看这种池内异步归还 池外回调兜底的双路径设计正是为了兼容不同来源指针的释放语义。异步申请/释放与流同步的关系这是理解流序内存池的关键点aclrtMemPoolFreeAsync只是把内存归还给内存池并不释放物理内存物理释放由阈值控制见下文因此归还动作天然安全——物理块仍归属池内不会被其他实体占用。而内存已归还、可被后续任务复用这一事实通过下发到同一 Stream 的管理任务天然保序后续任务在同一 Stream 中执行时必然晚于归还任务从而安全地复用该内存块。这正是无需显式同步即可管理内存的底层保证。对照传统方式的对比代码如下#include acl/acl_rt.h #include acl/acl.h int main() { typedef struct { ...... } ArgsInfo; void *ptr0 nullptr; aclrtStream stream1; // 异步申请内存,testReusePool为用户创建的内存池 aclrtMemPoolMallocAsync(ptr0, sizeof(ArgsInfo), testReusePool, stream1); ...... // 配置任务下发 ArgsInfo usrArgs; // 拷贝信息到device侧申请内存 error aclrtMemcpyAsync(ptr0, sizeof(ArgsInfo), (void *)usrArgs, sizeof(ArgsInfo), ACL_MEMCPY_HOST_TO_DEVICE, stream1); // 下发任务 uint32_t blockDim 32; aclrtLaunchKernelV2(funcHandle, blockDim, (void *)usrArgs, sizeof(ArgsInfo), nullptr, stream1); // 异步释放内存无需进行流同步 aclrtMemPoolFreeAsync(ptr0, stream1); ...... // 流同步 aclrtSynchronizeStream(stream1); return 0; }可以看到两次异步操作之间不再需要任何aclrtSynchronizeStream编程模型大幅简化。内存池创建与销毁aclrtMemPoolCreate / aclrtMemPoolDestroy接口签名与功能aclError aclrtMemPoolCreate(aclrtMemPool *memPool, const aclrtMemPoolProps *poolProps) aclError aclrtMemPoolDestroy(const aclrtMemPool memPool)aclrtMemPoolCreate创建内存池。memPool为输出参数返回内存池实例句柄poolProps为输入参数描述内存池配置。aclrtMemPoolDestroy销毁通过aclrtMemPoolCreate创建的内存池。memPool为输入参数。两个接口均返回 0 表示成功其他值表示失败错误码参见aclError。须知本组接口均为试验特性后续版本可能变更不支持应用于生产环境。产品支持情况从 docs/zh/api_ref/11-10_ordered_stream_memory_allocation.md 的产品支持矩阵看当前仅Atlas A2 训练系列产品/Atlas A2 推理系列产品支持该功能其余产品如 Atlas A3 系列、Atlas 训练系列、Ascend 950PR/950DT、IPV350 等均不支持使用前务必确认目标平台。内存池属性结构 aclrtMemPoolPropsaclrtMemPoolProps定义于 include/external/acl/acl_rt_memory_soma.htypedef struct { aclrtMemAllocationType allocType; aclrtMemHandleType handleType; aclrtMemLocation location; size_t maxSize; unsigned char reserved[32]; } aclrtMemPoolProps;各字段含义如下字段说明allocType内存分配类型当前仅支持ACL_MEM_ALLOCATION_TYPE_PINNED0。handleType内存句柄类型当前支持ACL_MEM_HANDLE_TYPE_NONE0默认与ACL_MEM_HANDLE_TYPE_POSIX2。location内存位置为aclrtMemLocation结构体包含id设备逻辑 ID与type内存位置类型。maxSize内存池最大容量单位 Byte即创建池时一次性预留的物理内存上限。reserved保留字段必须全 0。相关枚举定义在 include/external/acl/acl_rt.htypedef enum aclrtMemLocationType { ACL_MEM_LOCATION_TYPE_HOST 0, /** reserved enum, current version not support */ ACL_MEM_LOCATION_TYPE_DEVICE, ACL_MEM_LOCATION_TYPE_UNREGISTERED, ACL_MEM_LOCATION_TYPE_MANAGED, ACL_MEM_LOCATION_TYPE_HOST_NUMA 4, /*alloc host memeory via NUMA ID */ } aclrtMemLocationType; typedef struct aclrtMemLocation { uint32_t id; aclrtMemLocationType type; } aclrtMemLocation; typedef enum aclrtMemAllocationType { ACL_MEM_ALLOCATION_TYPE_PINNED 0, } aclrtMemAllocationType; typedef enum aclrtMemHandleType { ACL_MEM_HANDLE_TYPE_NONE 0, ACL_MEM_HANDLE_TYPE_POSIX 2, } aclrtMemHandleType;参数校验规则源码级ACL 封装层aclrtMemPoolCreateImplsrc/acl/aclrt_impl/memory.cpp在创建前执行如下强校验allocType必须为ACL_MEM_ALLOCATION_TYPE_PINNED否则返回ACL_ERROR_INVALID_PARAMlocation.type必须为ACL_MEM_LOCATION_TYPE_DEVICE即 1即当前仅支持设备内存池reserved字段必须全零否则拒绝创建。运行时层SomaApi::StreamMemPoolCreatesrc/runtime/feature/soma/soma.cc会进一步将用户 Device ID 转换为物理 Device IDChgUserDevIdToDeviceId通过MemGetInfoEx查询 HBM 空闲/总大小通过GetAllocationGranularity获取设备内存分配粒度推荐粒度失败时回退到DEVICE_POOL_ALIGN_SIZE并对maxSize做对齐与上限校验对齐后不得超过设备可用内存否则报错提示调用驱动StreamMemPoolCreate在驱动侧建立池并返回起始虚拟地址outVa随后PoolRegistry::InitializeMemPool初始化段管理器最后RegisterMemPool注册到全局池注册表中。一个完整的创建示例结合 docs/zh/api_ref/11-10_ordered_stream_memory_allocation.md 的示例代码一个完整的内存池创建流程如下uint32_t devid 0; aclInit(NULL); aclrtSetDevice(devid); // 创建Context和Stream aclrtContext context; aclrtStream stream1; aclrtCreateContext(context, 0); aclrtCreateStream(stream1); // 设置内存池属性 aclrtMemLocation testLoc { 0, // id ACL_MEM_LOCATION_TYPE_DEVICE // type }; aclrtMemPoolProps testProp { ACL_MEM_ALLOCATION_TYPE_PINNED, // allocType ACL_MEM_HANDLE_TYPE_NONE, // handleType testLoc, // location 14UL 30, // maxSize 14GB 内存池大小为14GB {0} // reserved }; // 创建内存池 aclrtMemPool testReusePool; auto ret aclrtMemPoolCreate(testReusePool, testProp); if (ret ! ACL_SUCCESS) { fprintf(stderr, Failed to create memory pool\n); return -1; }创建完成后内存池便以独立于普通堆的实体存在池内物理内存由驱动在创建时一次性预留后续分配/释放均在该池内进行从源码结构看这正是避免频繁向驱动申请/释放物理内存的性能前提。内存池属性配置与关键指标aclrtMemPoolSetAttr / aclrtMemPoolGetAttr接口签名与功能aclError aclrtMemPoolSetAttr(aclrtMemPool memPool, aclrtMemPoolAttr attr, void *value) aclError aclrtMemPoolGetAttr(aclrtMemPool memPool, aclrtMemPoolAttr attr, void *value)aclrtMemPoolSetAttr设置属性值多次对同一属性设置以最后一次为准。aclrtMemPoolGetAttr获取属性值若从未设置则返回该属性的默认值。属性枚举 aclrtMemPoolAttr 全解aclrtMemPoolAttr定义于 include/external/acl/acl_rt_memory_soma.h取值如下typedef enum aclrtMemPoolAttr { ACL_RT_MEM_POOL_REUSE_FOLLOW_EVENT_DEPENDENCIES 0x1, ACL_RT_MEM_POOL_REUSE_ALLOW_OPPORTUNISTIC 0x2, ACL_RT_MEM_POOL_REUSE_ALLOW_INTERNAL_DEPENDENCIES 0x3, ACL_RT_MEM_POOL_ATTR_RELEASE_THRESHOLD 0x4, ACL_RT_MEM_POOL_ATTR_RESERVED_MEM_CURRENT 0x5, ACL_RT_MEM_POOL_ATTR_RESERVED_MEM_HIGH 0x6, ACL_RT_MEM_POOL_ATTR_USED_MEM_CURRENT 0x7, ACL_RT_MEM_POOL_ATTR_USED_MEM_HIGH 0x8 } aclrtMemPoolAttr;各属性的完整语义依据 docs/zh/api_ref/25-02_Enumerations.md 的aclrtMemPoolAttr小节整理属性类型读写语义ACL_RT_MEM_POOL_REUSE_FOLLOW_EVENT_DEPENDENCIESuint32_t写事件依赖内存复用开关。执行某 Stream 任务时系统查找与该 Stream 通过 Event 关联的其他 Stream复用其中任务已归还的内存。适用于以 Event 实现 Stream 间同步的应用程序。1启用0关闭。ACL_RT_MEM_POOL_REUSE_ALLOW_OPPORTUNISTICuint32_t写机会主义内存复用开关。执行某 Stream 任务时系统检索池中可复用内存但不保证一定成功复用失败时程序报错停止。1启用0关闭。ACL_RT_MEM_POOL_REUSE_ALLOW_INTERNAL_DEPENDENCIESuint32_t写隐式依赖内存复用开关。若待复用内存曾被其他无任务依赖关系的 Stream 使用系统自动在相关 Stream 间增加 Event 同步等待逻辑确保前序访问结束实现安全复用。1启用0关闭。ACL_RT_MEM_POOL_ATTR_RELEASE_THRESHOLDuint64_t读写释放空闲物理内存时池中要保留的内存大小阈值单位 Byte默认值为 0。当池内空闲物理内存超过该阈值时在下一次 Stream 同步如aclrtSynchronizeStream时系统尝试真正释放超出的空闲内存。ACL_RT_MEM_POOL_ATTR_RESERVED_MEM_CURRENTuint64_t只读内存池中当前被申请Reserved的内存总量。ACL_RT_MEM_POOL_ATTR_RESERVED_MEM_HIGHuint64_t读写池中当前被申请内存总量的历史峰值。设置时属性值只能为 0即清零峰值。ACL_RT_MEM_POOL_ATTR_USED_MEM_CURRENTuint64_t只读内存池中实际正在使用Used的内存总量。ACL_RT_MEM_POOL_ATTR_USED_MEM_HIGHuint64_t读写池中实际正在使用内存总量的历史峰值。设置时属性值只能为 0即清零峰值。关键指标区分Reserved vs Used、Current vs High关联文档强调需要理解内存池阈值、保留内存与已用内存等关键指标这里给出精确区分Reserved保留/被申请表示已从池中划出、被应用占用的内存总量。aclrtMemPoolMallocAsync成功一次RESERVED_MEM_CURRENT就增加对应对齐后大小aclrtMemPoolFreeAsync归还一次则减少。Used已用表示当前实际被使用的内存。它与 Reserved 的差异主要出现在池外回调路径从源码实现看当aclrtMemPoolFreeAsync释放的指针不属于 SOMA 池区域时会注册 Host 回调真正释放物理内存此时 Reserved 与 Used 的统计口径就会产生分化。Current当前值实时快照用于监控。High历史峰值自创建或清零以来达到的最大值用于评估内存池容量规划是否合理可通过写入 0 重置。从驱动侧实现src/runtime/driver/npu_driver_standard_soc.cc 的ConvertMemPoolAttr可以看到RELEASE_THRESHOLD、RESERVED_MEM_CURRENT/HIGH、USED_MEM_CURRENT/HIGH会原样映射为驱动侧MEM_POOL_ATTR_*枚举即这些指标由驱动侧统一维护Runtime 通过halMemPoolSetAttr/halMemPoolGetAttr驱动接口透传。阈值与物理释放的联动机制释放时机默认阈值 0情况下空闲内存超过 0 即触发下一次 Stream 同步时尝试真正释放空闲物理内存的逻辑。合理设置阈值可以保留一部分空闲内存避免频繁向驱动申请/归还是性能与内存占用之间的权衡旋钮。手动收缩aclrtMemPoolTrimTo可直接主动收缩见下文。优先级若同时通过aclrtMemPoolSetAttr配置了ACL_RT_MEM_POOL_ATTR_RELEASE_THRESHOLD阈值又通过aclrtMemPoolTrimTo的minBytesToKeep指定保留大小后者TrimTo优先级更高。异步分配与内存复用aclrtMemPoolMallocAsync / aclrtMemPoolFreeAsync接口签名aclError aclrtMemPoolMallocAsync(void **ptr, size_t size, aclrtMemPool memPool, aclrtStream stream) aclError aclrtMemPoolFreeAsync(void *ptr, aclrtStream stream)aclrtMemPoolMallocAsync从内存池异步申请size单位 Byte须大于 0内存输出到ptrstream指定承载该分配任务的 Stream。aclrtMemPoolFreeAsync异步释放ptr指向的内存。仅将内存归还内存池并不实际释放物理内存以便后续任务复用。两者的异步语义均体现在操作被包装为 Stream 上的任务申请侧为SomaMemMngAICore 管理内核释放侧为归还 管理内核/回调随 Stream 保序执行调用方无需提前aclrtSynchronizeStream。内存复用机制调用aclrtMemPoolFreeAsync归还内存后物理内存并不归还给驱动而是留在池内供后续任务复用从而避免频繁申请/释放物理内存。复用时会按本次任务所需大小从池中选取大小最接近的空闲内存块尽可能降低碎片与扩容开销。复用场景分为三类与上述三个REUSE_*属性开关一一对应单个 Stream 内复用执行某 Stream 任务时系统查找该 Stream 前序任务已归还到池中的内存并复用是最基础的复用路径。Stream 间复用细分为事件依赖复用对应REUSE_FOLLOW_EVENT_DEPENDENCIES复用通过 Event 与该 Stream 关联的其他 Stream 已归还的内存适用于用 Event 做 Stream 间同步的应用。机会主义复用对应REUSE_ALLOW_OPPORTUNISTIC尽力检索可复用内存不保证成功失败时报错停止。隐式依赖复用对应REUSE_ALLOW_INTERNAL_DEPENDENCIES若待复用内存曾被无依赖关系的其他 Stream 使用系统自动插入 Event 同步等待保证前序访问结束后再复用兼顾安全与效率。从实现层面看运行时通过SomaApi::AllocFromMemPool(devPtr, alignedSize, memPoolId, streamId, flag)传入复用标志ReuseFlag结合MemPoolAsyncConfig对驱动的异步配置见 src/runtime/driver/npu_driver_standard_soc.cc 的StreamMemPoolAsyncConfig将该块可复用/被复用的状态同步到驱动从而让驱动在后续分配时做出复用决策。完整实战示例以下示例完整串联创建池、异步申请、算子下发、异步归还与销毁摘自 docs/zh/api_ref/11-10_ordered_stream_memory_allocation.md仅作参考需根据实际环境调整#include stdio.h #include string.h #include unistd.h #include time.h #include gtest/gtest.h #include acl/acl_rt.h #include acl/acl.h int main() { uint32_t devid 0; aclInit(NULL); aclrtSetDevice(devid); // 创建Context和Stream aclrtContext context; aclrtStream stream1; aclrtCreateContext(context, 0); aclrtCreateStream(stream1); // 设置内存池属性 aclrtMemLocation testLoc { 0, // id ACL_MEM_LOCATION_TYPE_DEVICE // type }; aclrtMemPoolProps testProp { ACL_MEM_ALLOCATION_TYPE_PINNED, // allocType ACL_MEM_HANDLE_TYPE_NONE, // handleType testLoc, // location 14UL 30, // maxSize 14GB 内存池大小为14GB {0} // reserved }; // 创建内存池 aclrtMemPool testReusePool; auto ret aclrtMemPoolCreate(testReusePool, testProp); if (ret ! ACL_SUCCESS) { fprintf(stderr, Failed to create memory pool\n); return -1; } const size_t GB_TO_B 1024ULL * 1024 * 1024; // 定义算子信息结构体 typedef struct { void *input_x; void *input_y; void *output_z; } ArgsInfo; aclrtBinHandle bin_handle nullptr; aclrtFuncHandle func_handle; aclError aclrtBinaryGetFunction(binHandle, add_custom, funcHandle); void *ptr0 nullptr; void *ptr1 nullptr; void *ptr2 nullptr; void *ptr3 nullptr; // 异步申请内存 aclrtMemPoolMallocAsync(ptr1, sizeof(uint64_t), testReusePool, stream1); aclrtMemPoolMallocAsync(ptr2, sizeof(uint64_t), testReusePool, stream1); aclrtMemPoolMallocAsync(ptr3, sizeof(uint64_t), testReusePool, stream1); aclrtMemPoolMallocAsync(ptr0, sizeof(ArgsInfo), testReusePool, stream1); // 配置任务下发 ArgsInfo usrArgs; usrArgs.input_x ptr1; usrArgs.input_y ptr2; usrArgs.output_z ptr3; error aclrtMemcpyAsync(devPtr, sizeof(ArgsInfo), (void *)usrArgs, sizeof(ArgsInfo), ACL_MEMCPY_HOST_TO_DEVICE, stream1); // 下发任务 uint32_t blockDim 32; aclrtLaunchKernelV2(funcHandle, blockDim, (void *)usrArgs, sizeof(ArgsInfo), nullptr, stream1); // 异步释放内存此前无需进行流同步 aclrtMemPoolFreeAsync(ptr0, stream1); aclrtMemPoolFreeAsync(ptr1, stream1); aclrtMemPoolFreeAsync(ptr2, stream1); aclrtMemPoolFreeAsync(ptr3, stream1); // 流同步 aclrtSynchronizeStream(stream1); // 销毁内存池、Stream和Context aclrtMemPoolDestroy(testReusePool); aclrtDestroyStream(stream1); aclrtDestroyContext(context); aclrtResetDevice(devid); aclFinalize(); return 0; }与常规 aclrtMalloc/aclrtFree 的适用场景对比维度aclrtMalloc / aclrtFreeaclrtMemPoolMallocAsync / aclrtMemPoolFreeAsync同步语义同步接口释放前必须aclrtSynchronizeStream保证内存空闲异步接口操作进入 Stream 调度序列依赖 Stream 保序无需显式同步物理内存行为每次申请/释放都直接作用于物理内存归还仅回池物理内存延迟释放由阈值/TrimTo 控制内存复用无支持池内复用单 Stream 内及 Stream 间三种模式使用复杂度简单直观需先建池、配置属性复杂度更高适用场景低频、一次性分配大量算子下发、高频申请/释放、追求流水线性能的场景主动收缩内存池aclrtMemPoolTrimTo接口签名aclError aclrtMemPoolTrimTo(aclrtMemPool memPool, size_t minBytesToKeep)功能说明收缩内存池保留minBytesToKeep字节的物理内存释放其余空闲物理内存不影响当前正在使用的内存。由于aclrtMemPoolFreeAsync只归还、不释放空闲内存会持续占用池容量极端情况下可能导致aclrtMemPoolMallocAsync无法申请到新内存池容量已满。此时调用aclrtMemPoolTrimTo可主动回收未使用的物理内存。它与ACL_RT_MEM_POOL_ATTR_RELEASE_THRESHOLD的差别在于阈值属性是惰性释放——在下次 Stream 同步时按阈值判断是否释放TrimTo是主动收缩——调用即刻生效且minBytesToKeep优先级高于阈值配置。运行时内部与普通内存池的协同值得注意的是仓库中还维护了一套非 SOMA 的普通设备内存池机制src/runtime/core/src/pool/memory_pool_manager.cc两者并存但职责不同MemoryPoolManager服务于常规aclrtMalloc/aclrtFree等同步分配路径按需创建MemoryPool实例Allocate时若无可用池则AddMemoryPool单块分配超过 2MBPOOL_SIZE_2M时直接不走池它采用空闲池超过maxFreePools_阈值即回收的策略CheckAndReleasePools并用读写锁保护并发memory_pool_manager.cc而流序内存池由PoolRegistry统一管理SegmentManager走驱动halMemPoolCreate/halMemPoolAsyncConfig接口soma.cc、npu_driver_standard_soc.cc二者分别服务同步与异步两条内存管理通路。理解这一区分有助于在排查问题时快速定位同步接口的池化行为看MemoryPoolManager流序池的行为看 SOMA 栈。总结与建议流序内存池将内存管理任务化 池化 复用化是针对高频异步任务场景的高阶内存方案。落地时的要点可归结为先确认平台当前仅 Atlas A2 训练/推理系列产品支持其他平台调用会返回功能不支持错误。合理设定maxSize创建时即预留物理内存过大浪费显存过小则复用价值有限需结合业务峰值与USED_MEM_HIGH/RESERVED_MEM_HIGH指标校准。配置复用开关与释放阈值根据 Stream 间是否存在 Event 依赖选择合适的REUSE_*开关并用RELEASE_THRESHOLD平衡内存占用与释放频率需要即刻回收时调用aclrtMemPoolTrimTo。遵循异步语义申请/归还均按 Stream 保序无需在归还前显式同步但最终仍需一次aclrtSynchronizeStream完成整条流水线的收尾。监控指标通过aclrtMemPoolGetAttr读取RESERVED_MEM_CURRENT/HIGH与USED_MEM_CURRENT/HIGH用 Current 观察实时水位、用 High 评估容量规划。相关文档与源码入口功能索引 example/3_memory_advanced/memory_pool/README_en.md及 中文版、API 手册 docs/zh/api_ref/11-10_ordered_stream_memory_allocation.md、属性枚举说明 docs/zh/api_ref/25-02_Enumerations.md、头文件 include/external/acl/acl_rt_memory_soma.h、实现源码 src/runtime/feature/soma/soma.cc 与 src/runtime/api/impl/api_impl_soma.cc。【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价