CANN SHMEM 设备侧 SDMA NotifyWait 机制使用指南:显式 QP 多核并发与无 QP 单核搬运实战
CANN SHMEM 设备侧 SDMA NotifyWait 机制使用指南显式 QP 多核并发与无 QP 单核搬运实战【免费下载链接】shmemCANN SHMEM 是面向昇腾平台的多机多卡内存通信库基于OpenSHMEM 标准协议实现跨设备的高效内存访问与数据同步。项目地址: https://gitcode.com/cann/shmem本文围绕 CANN SHMEM 开源仓库中的notifywait示例README_en.md展开系统讲解设备侧 SDMASystem DMA异步数据搬运与 NotifyWait 完成通知机制如何在指定 SDMA QP 上下发 record 类型的 SQE、在 Host 侧通过aclrtWaitAndResetNotify等待通知以及显式 QP 接口与无 QP 接口的差异与选型。读完本文你将掌握notifywait示例的编译运行方法、容量与 AIV 限制评估以及基于 SDMA 的 AllGather 多核/单核两种实现路径并能在自己的算子中直接复用这套搬运 通知 等待的流水线同步模式。一、机制概览为什么需要 NotifyWait在昇腾设备侧SDMA 引擎承担 GM 与 GM 之间、GM 与 UB 之间的高速数据搬运。aclshmemx_sdma_qp_put_nbi/aclshmemx_sdma_qp_get_nbi这类接口是**非阻塞nbi non-blocking**的——函数返回只代表 SQE 已提交到 QP并不代表搬运完成。因此调用方必须通过某种手段确认数据就绪后才能安全地消费数据或复用工作区。CANN SHMEM 提供两种完成确认方式aclshmemx_sdma_qp_quiet在 AIV 内轮询 flag直到指定 QP 上的 SQE 全部完成。缺点是该 AIV 被阻塞在轮询循环中无法及时释放。NotifyWait本示例的主题在数据搬运后追加一条 record 类型的 SQE由 Host 侧aclrtWaitAndResetNotify等待通知等待完成后 AIV 已提前释放后续 kernel 可直接使用搬运结果。其核心思路可用三步概括Kernel 1stream 1搬运数据并记录通知 → Host 等待并复位 notify → Kernel 2stream 2消费数据。相比quiet的 AIV 轮询NotifyWait 让 Host 承担等待职责从而及时释放 AIV 资源见 README_en.md。二、环境要求与软件准备SDMA 功能是较新的能力有明确的软件版本门槛CANN 版本SDMA 功能需要 CANN 9.0.0 及以上版本trial 版支持中文版 README.md 中标注为 CANN 9.0.0-beta.2 及以上。需要安装Toolkit 包与ops-legacy 包两类软件包ops 包需根据硬件平台A2/A3、x86_64/aarch64选择与 toolkit 版本匹配的版本。平台限制当前暂不支持 Ascend950平台配套编译运行SDMA 写操作在 Ascend950 上不受支持见 shmem_device_sdma.h 中相关接口注释。运行环境PES 仅支持 2、4、8 卡且限定在单台机器内数据通过 TCP 环回地址默认tcp://127.0.0.1:8766进行初始化通信。三、编译与运行示例3.1 三步编译运行流程按照 README_en.md 的操作顺序在仓库根目录shmem/下编译软件包并安装bash scripts/build.sh -package ./install/*/SHMEM_1.0.0_linux-*.run --install在仓库根目录shmem/下编译所有 examplesbash scripts/build.sh -examples进入shmem/examples/notifywait目录运行 demobash run.sh -pes ${PES} -type ${TYPES}参数说明来自文档PES用于运行 demo 的设备NPU数量仅支持 2、4、8 卡限定单台机器内。TYPES传输的数据类型当前支持int、uint8、int64、fp32。3.2 运行脚本支持的全部参数run.sh 实际还支持更多命令行选项可通过-键 值的方式传入参数含义默认值-pes进程/PE 数量2若-gnpus大于该值会自动收敛为-pes值-type数据类型int / uint8 / int64 / fp32int-ipport初始化通信 IP 端口tcp://127.0.0.1:8766-fpe起始 PE 编号0-gnpus使用的 NPU 数量对应每卡一个进程8-fnpu起始 NPU 编号0-pe_tablePE 映射表空脚本内部会导出SHMEM_UID_SESSION_ID127.0.0.1:8899作为 UID 会话标识并将${PROJECT_ROOT}/build/lib与${ASCEND_HOME_PATH}/lib64加入LD_LIBRARY_PATH随后为每个 NPU 拉起一个后台进程等待全部进程结束后统一返回退出码。四、容量与 AIV 限制运行前必读文档明确给出了本示例的资源预算运行前需要据此评估硬件是否满足条件对称内存容量示例申请128M * sizeof(T)字节的对称空间其中输入区与结果区各需PES * 8M * sizeof(T)字节。以 8 卡、int4 字节为例即每个 PE 需约128M * 4B 512MB对称空间。文档支持矩阵为 2、4、8 卡实际可用卡数还需满足对称空间与运行环境的容量条件。在 main.cpp 中可看到symmetric_elements 128 * 1024 * 1024、trans_size 8 * 1024 * 1024的定义。SDMA 共享 workspace为 28 KiB。按 A5 平台最大 72 个 AIV/QP 计算notify ID 区域与三组 flag 区域共需14 KiB 72 * 4 B 3 * 72 * 64 B 28,448 B恰好剩余 224 B空间足够。AIV/QP 数量当前 kernel 启动 20 个 block每个 block 含 2 个 subblockAIV实际使用 40 个 AIV/QP底层基础设施和 notify 数组已按最多72 个 AIV/QP预留。上报 vector core 数超过 72 的设备当前返回不支持。对应的常量定义位于 main.cppSDMA_AIVS_PER_BLOCK 2、SDMA_BLOCK_NUM 20、SDMA_QP_NUM SDMA_BLOCK_NUM * SDMA_AIVS_PER_BLOCK 40并在初始化时通过aclshmemx_set_qp_num(ACLSHMEM_DATA_OP_SDMA, SDMA_QP_NUM)配置 SDMA 通道数main.cpp同时将attributes.option_attr.data_op_engine_type置为ACLSHMEM_DATA_OP_SDMA以启用 SDMA 数据通路。五、NotifyWait 三步用法详解5.1 用法示例notifywait 机制三步流程示意整个机制分为三个步骤对应 README_en.md 中的伪代码// 步骤 1 // stream 1 上的 kernel 1调用显式 QP 的 SDMA 接口搬运数据并追加 aclshmemx_sdma_qp_notify_record // 步骤 2 // HostaclrtWaitAndResetNotify(notify_id, stream2, 0) // 步骤 3 // stream 2 上的 kernel 2使用 SDMA 搬运好的数据5.2 原理record 类型 SQE 与 Host 侧等待在aclshmemx_sdma_qp_notify_record中会向选定的 STARS QP下发一条 record 类型的 SQE。由于 SQE 在 QP 内保序这条 record 通知会排在之前提交的所有搬运 SQE 之后因此 Host 等待到该通知时即可确认此前该 QP 上的搬运全部完成。随后 Host 再调度后续 kernel天然形成了搬运完成 → 数据可用的依赖关系。相比aclshmemx_sdma_qp_quiet依赖AIV 轮询 flag的方式NotifyWait 将等待从 AIV 转移到 Host从而及时释放 AIV 资源让 AIV 可以立即投入其他计算任务。设备侧实现可在 shmem_device_sdma.hpp 中看到aclshmemi_stars_submit_notify_record通过notify_addr[qp_idx]定位到对应 QP 的通知地址并填充 record SQE无 QP 变体则固定向 QP 0 追加通知aclshmemi_stars_submit_notify_record(ub_tensor, sync_id, 0)。Host 侧的 notify 对象由 SDMA 传输管理模块在初始化阶段创建通过aclrtCreateNotify为每个 QP 创建 notify、aclrtGetNotifyId获取 notify ID并在结束时用aclrtDestroyNotify销毁见 device_sdma_transport_manager.cpp。示例中 Host 通过g_state_host.notify_arr[i]数组按 QP 索引一一对应等待main.cpp。六、显式 QP 的 SDMA 接口多核 AllGather 实现6.1 接口形态显式 QP 接口相比无 QP 接口多一个qp_idx参数且提供__ubuf__指针与AscendC::GlobalTensor/LocalTensor两套重载。核心接口签名完整声明见 shmem_device_sdma.htemplate typename T void aclshmemx_sdma_qp_put_nbi(__gm__ T* dst, __gm__ T* src, __ubuf__ T* buf, uint32_t ub_size, uint32_t elem_size, int pe, uint32_t qp_idx, uint32_t sync_id); template typename T void aclshmemx_sdma_qp_get_nbi(__gm__ T* dst, __gm__ T* src, __ubuf__ T* buf, uint32_t ub_size, uint32_t elem_size, int pe, uint32_t qp_idx, uint32_t sync_id); template typename T void aclshmemx_sdma_qp_notify_record(__ubuf__ T* buf, uint32_t ub_size, uint32_t qp_idx, uint32_t sync_id);dst/src对称地址会在指定 PE 上做地址翻译或本设备 GM 地址dst/src需落在同一个对称分配块内。buf/ub_sizeUB 工作区地址必须64 字节对齐大小至少 64 字节。elem_size搬运的元素个数elem_size * sizeof(T)不得超过UINT32_MAX字节。pe对端 PE必须处于已初始化的 PE 范围内。qp_idxSDMA QP 索引必须小于已配置的 SDMA 通道数QP 索引与 block 索引相互独立。sync_id流水线同步使用的硬件事件 ID。6.2 多核 allgather_sdma 内核main.cpp 中的allgather_sdma内核演示了显式 QP 的标准用法每个 AIV 根据GetBlockIdx()计算出自己负责的连续数据区间base_per_core/extra_bytes按元素均摊切分保证各 AIV 负载均衡循环向除自身外的每个 PE 调用aclshmemx_sdma_qp_put_nbi或get_nbi每个 AIV 使用与自身编号相同的 QP收发数据全部搬运提交后调用aclshmemx_sdma_qp_notify_record在本 QP 上追加通知。Host 侧对 40 个 QP 逐个等待for (int i 0; i total_block_num * sub_block_num; i) { CHECK_RET(aclrtWaitAndResetNotify(g_state_host.notify_arr[i], g_state_host.default_stream, 0)); }需要说明的是接口的完成语义是函数正常返回仅代表请求已提交不代表搬运完成。在显式 QP 场景下不能用aclshmemx_sdma_quiet它只排空 QP 0来等待qp_idx 0的请求而应使用同 QP 的aclshmemx_sdma_qp_quiet或如本例一样追加aclshmemx_sdma_qp_notify_record并在 Host 等待shmem_device_sdma.h 的接口注释对此有明确说明。示例还提供了allgather_sdma_tensor内核main.cpp展示GlobalTensor/LocalTensor重载的等价用法。七、不带 QP 的 SDMA 接口单核 AllGather 实现除显式 QP 接口外示例还演示了不带 QP 的 SDMA 接口。二者接口形态接近区别是不带 QP 的接口固定使用 QP 0、无需传入qp_idx属于单核单 AIV接口// 异步搬运固定使用 QP 0 template typename T void aclshmemx_sdma_put_nbi(__gm__ T* dst, __gm__ T* src, __ubuf__ T* buf, uint32_t ub_size, uint32_t elem_size, int pe, uint32_t sync_id); // 在 QP 0 上追加 notify recordHost 侧等待 notify_arr[0] 即可 template typename T void aclshmemx_sdma_notify_record(__ubuf__ T* buf, uint32_t ub_size, uint32_t sync_id);对应实现为 main.cpp 中的allgather_sdma_noqp内核仅由 0 号 AIV 执行其余 AIV 直接返回对本 PE 的数据做整块搬运无需按 AIV 切分并在 QP 0 上记录 notify// kernel 内仅 0 号 AIV 执行 aclshmemx_sdma_put_nbi(dst, src, tmp_buff, ub_size, size, pe, EVENT_ID0); aclshmemx_sdma_notify_record(tmp_buff, ub_size, EVENT_ID0); // host 侧只等待 1 个 notifyQP 0 对应 notify_arr[0] aclrtWaitAndResetNotify(g_state_host.notify_arr[0], stream, 0);与显式 QP 接口的对比对比项不带 QP 接口显式 QP 接口使用的 QP固定 QP 0通过qp_idx指定可用满已创建的全部 QP执行方式单 AIV 执行多 AIV 并发每个 AIV 使用独立 QP数据切分无需切分整块搬运需按 AIV 切分数据Host 等待仅notify_arr[0]每个 QP 各等待一次 notify适用场景单核简单收发、快速验证多核并发、带宽敏感场景八、运行验证与结果解读运行run.sh时demo 的执行顺序是固定的见 main.cpp显式 QP 多核 AllGatherallgather_sdma内核搬运 → Host 等待 40 个 notify →aclshmem_barrier_all()同步 → 用 MTE 将结果拷入结果区 → Host 校验控制台打印after notify_wait段的结果无 QP 单核 AllGatherallgather_sdma_noqp内核整块搬运 → Host 等待notify_arr[0]→aclshmem_barrier_all()同步 → 拷贝并校验控制台打印after sdma_put_nbi (no QP)段的结果。两段校验逻辑相同逐元素比对结果区中每个 PE 贡献的数据是否等于num10 inum10 10并统计异常值个数若异常值均为 0则说明对应阶段的搬运与通知机制工作正常。最终每个 PE 打印[SUCCESS] demo run success in pe N表示整体通过。九、总结NotifyWait 机制为 CANN SHMEM 设备侧 SDMA 异步搬运提供了一条搬运即通知、Host 等待、流间接力的同步链路aclshmemx_sdma_qp_notify_record在指定 QP 追加 record SQEHost 以aclrtWaitAndResetNotify等待避免了quiet方案中 AIV 轮询 flag 的资源占用。notifywait示例同时给出了两种工程范式——显式 QP 的多核并发 AllGather每 AIV 一 QP、按 AIV 切分数据与无 QP 的单核快速验证 AllGather固定 QP 0、整块搬运配合本文给出的容量评估方法可直接迁移到其他基于 SDMA 的集合通信或流水线算子设计中。进一步阅读完整的中文说明见 README.md接口头文件见 shmem_device_sdma.h设备侧实现见 shmem_device_sdma.hppHost 侧 notify 生命周期管理见 device_sdma_transport_manager.cpp。【免费下载链接】shmemCANN SHMEM 是面向昇腾平台的多机多卡内存通信库基于OpenSHMEM 标准协议实现跨设备的高效内存访问与数据同步。项目地址: https://gitcode.com/cann/shmem创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Front-End-Checklist 集成测试规则解读:为核心工作流编写高价值的集成测试

Front-End-Checklist 集成测试规则解读:为核心工作流编写高价值的集成测试

Front-End-Checklist 集成测试规则解读:为核心工作流编写高价值的集成测试 【免费下载链接】Front-End-Checklist 🗂 The essential checklist for modern web development, for humans and AI agents 项目地址: https://gitcode.com/gh_mirrors/fr/Fr…

2026/9/21 2:04:07 阅读更多 →
Vuetify 无限滚动组件 `v-infinite-scroll` 完全指南:自动/手动加载、双向滚动与虚拟化实战

Vuetify 无限滚动组件 `v-infinite-scroll` 完全指南:自动/手动加载、双向滚动与虚拟化实战

Vuetify 无限滚动组件 v-infinite-scroll 完全指南:自动/手动加载、双向滚动与虚拟化实战 【免费下载链接】vuetify 🐉 Vue Component Framework 项目地址: https://gitcode.com/gh_mirrors/vu/vuetify v-infinite-scroll 是 Vuetify 内置的无限滚…

2026/9/21 0:47:06 阅读更多 →
5 分钟搞定 Composio Tool Router:多用户 MCP 会话隔离与工具精细管控

5 分钟搞定 Composio Tool Router:多用户 MCP 会话隔离与工具精细管控

5 分钟搞定 Composio Tool Router:多用户 MCP 会话隔离与工具精细管控 【免费下载链接】composio Composio powers 1000 toolkits, tool search, context management, authentication, and a sandboxed workbench to help you build AI agents that turn intent int…

2026/9/21 0:47:37 阅读更多 →

最新新闻

高中物理必刷题PDF高效使用指南:模型识别与三轮刷题法

高中物理必刷题PDF高效使用指南:模型识别与三轮刷题法

简介:这是一份面向高考物理备考生的《高中物理高考必刷题-题目解析版》PDF文档,涵盖超声波测距、匀变速直线运动、自由落体、竖直上抛逆向思维、牛顿运动定律及地球自转对物体运动影响等核心考点,并结合历年真题与易错题进行详细解析&#xf…

2026/9/21 2:04:06 阅读更多 →
AI技术周报:高效筛选与解读行业动态

AI技术周报:高效筛选与解读行业动态

1. 项目概述"每周AI新鲜事儿"这个栏目名称已经透露了它的核心定位——一个定期更新的AI领域资讯聚合平台。作为长期跟踪技术趋势的从业者,我深知在这个信息爆炸的时代,专业筛选的价值有多大。每周260320这个日期编码(2023年3月20日…

2026/9/21 2:04:06 阅读更多 →
STM32 HAL库驱动ESP8266实战:从CubeMX配置到AT指令收发框架

STM32 HAL库驱动ESP8266实战:从CubeMX配置到AT指令收发框架

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/21 2:04:06 阅读更多 →
15个生活化比喻轻松理解AI核心技术

15个生活化比喻轻松理解AI核心技术

1. 项目概述:用生活化比喻拆解AI核心概念去年在给团队做内部培训时,我发现一个有趣现象:当用"快递驿站"比喻机器学习中的梯度下降时,新同事眼睛突然亮了起来。这促使我系统整理了15个类似的比喻,帮助不同背景…

2026/9/21 2:04:06 阅读更多 →
LibreChat:本地化AI智能工作台与Agent架构实践指南

LibreChat:本地化AI智能工作台与Agent架构实践指南

1. LibreChat 是什么?一个能跑在你本地的、真正开源的 AI 聊天界面 LibreChat 不是另一个套壳 OpenAI 官网的网页前端,也不是只支持单一模型的玩具项目。它是一个从零开始构建的、功能完整的、可自托管的开源聊天应用,核心目标非常明确&…

2026/9/21 2:04:06 阅读更多 →
RV1126平台JD9366触摸屏驱动移植实战指南

RV1126平台JD9366触摸屏驱动移植实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/21 2:03:06 阅读更多 →

日新闻

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程 【免费下载链接】agentic-awesome-skills AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and …

2026/9/21 0:00:01 阅读更多 →
gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析 【免费下载链接】gin-vue-admin 🚀ViteVue3Gin拥有AI辅助的基础开发平台,企业级业务AI开发解决方案,内置mcp辅助服务,内置skills管理,…

2026/9/21 0:00:01 阅读更多 →
Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

桌面应用AI 应用插件系统 【免费下载链接】Wox A cross-platform launcher that simply works 项目地址: https://gitcode.com/gh_mirrors/wo/Wox 点击查看 免费下载 全功能插件(Full-featured Plugin)是 Wox 三类插件实现方式中能力最完整的…

2026/9/21 0:00:01 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/20 0:00:46 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/20 0:00:46 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/20 0:00:46 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/19 23:01:36 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/19 17:50:38 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/19 23:35:34 阅读更多 →