CANN 组织链接: https://atomgit.com/cann
Runtime 仓库链接: https://atomgit.com/cann/runtime


在 CANN (Compute Architecture for Neural Networks) 的全栈软件体系中,Runtime 组件扮演着承上启下的关键角色。作为应用程序与底层硬件之间的神经中枢,Runtime 不仅要屏蔽底层异构设备的复杂控制细节,还要负责将图引擎(GE)生成的计算图高效地映射为硬件指令流。它管理着从上下文创建、内存分配、流同步到任务异常处理的全生命周期,是保障 AI 任务在 NPU 上高性能、确定性执行的基石。

1. 异步流(Stream)与事件(Event)驱动的并行调度

Runtime 的核心执行模型基于异步流设计。在异构计算中,Host(CPU)与 Device(NPU)之间的通信延迟是影响端到端性能的主要瓶颈。Runtime 通过构建软件层面的任务队列,最大化地掩盖了这种延迟。

1.1 Stream 的生命周期与任务序列化

Stream 是 Device 上按顺序执行的任务队列。Runtime 允许上层应用创建多个 Stream,并保证同一 Stream 内的任务严格串行,而不同 Stream 间的任务则由硬件调度器(Task Scheduler)尝试并行执行。

  • 非阻塞提交:Host 侧调用 Kernel Launch 或 Memcpy Async 接口时,Runtime 仅将任务描述符(Task Descriptor)压入 Ring Buffer 后即刻返回,不等待 Device 执行完成。
  • 硬件级调度:NPU 内部的调度器会轮询这些 Ring Buffer,一旦发现就绪任务且计算资源空闲,立即分发到 AI Core 或 DMA 引擎。

1.2 基于 Event 的细粒度同步

为了解决不同 Stream 之间的数据依赖问题,Runtime 引入了 Event 机制。Event 充当了流之间的“栅栏”或“信号灯”。

  • Record 与 Wait 原语aclrtRecordEvent 会在指定 Stream 的指令流中插入一个标记,当硬件执行到此处时触发信号;aclrtStreamWaitEvent 则会让另一 Stream 暂停执行后续指令,直到接收到该信号。
  • Device 侧闭环:关键在于,这种同步完全在 NPU 内部完成,无需 Host CPU 介入轮询或中断处理,从而实现了微秒级的同步低延迟。
// 典型的计算与搬运重叠(Overlap)代码模式
aclrtStream stream_compute, stream_copy;
aclrtEvent event_copy_done;

// Stream 1: 负责数据搬运
aclrtMemcpyAsync(dev_ptr, host_ptr, size, ACL_MEMCPY_HOST_TO_DEVICE, stream_copy);
// 插入事件记录点,硬件执行完 Memcpy 后触发
aclrtRecordEvent(event_copy_done, stream_copy);

// Stream 2: 负责计算
// 硬件等待 Stream 1 的搬运完成信号,CPU 不阻塞
aclrtStreamWaitEvent(stream_compute, event_copy_done);
// 启动计算核心
aclrtLaunchKernel(kernel_func, dim, stream_compute);

1.3 默认流与显式流的竞争仲裁

Runtime 维护了一个默认流(Default Stream)用于处理未指定 Stream 的遗留代码或简单任务。为了防止默认流成为瓶颈,Runtime 内部实现了优先级仲裁逻辑,确保显式创建的高优先级流能够抢占硬件资源,这对于对延迟敏感的推理服务至关重要。

2. 异构内存管理:池化与对齐策略

高效的显存(HBM)管理是 AI 性能优化的深水区。Runtime 并没有简单地透传 malloc 调用,而是实现了一套复杂的用户态内存管理系统。

2.1 内存池(Memory Pool)与碎片治理

频繁的系统调用(Syscall)申请物理内存极其昂贵。Runtime 在进程初始化阶段,会预先向内核驱动申请大块连续物理内存,构建内存池。

  • 分级分配算法:针对不同大小的 Tensor 申请(如小的标量 vs 大的 Feature Map),Runtime 采用类似 Slab 或 Buddy System 的算法进行快速分配,将分配开销降低至纳秒级。
  • 异步回收机制:内存的释放(Free)操作通常是异步的。Runtime 会追踪内存块关联的 Event 或 Stream 状态,只有当所有引用该内存块的计算任务都执行完毕后,才会真正将其归还到池中,防止 Use-After-Free 错误。

2.2 严格的地址对齐与 Padding

NPU 内部的数据搬运引擎(MTE)和向量计算单元对内存地址有严格要求。Runtime 在分配内存时,会自动处理这些硬件约束:

  • Bus Width 适配:分配的起始地址通常按照 64 字节或 512 字节对齐,以确保 MTE 能够启用最高效的 Burst 传输模式。
  • 尾部填充:对于不满足对齐要求的 Tensor 大小,Runtime 会自动进行尾部 Padding,防止 DMA 操作越界影响相邻的内存块。

2.3 页锁定内存(Pinned Memory)

在 Host 侧,Runtime 提供了分配页锁定内存的接口。这类内存通过 OS 内核锁定,不会被 Swap 换出到磁盘。这使得 NPU 的 DMA 引擎可以直接访问 Host 物理内存进行数据拉取,绕过了 CPU Cache 和额外的内核缓冲区拷贝,大幅提升 PCIe 传输带宽。

3. 图执行模式与计算任务下沉

为了突破 Host CPU 的调度瓶颈,Runtime 支持将一系列算子打包成“图”进行整体调度,这就是关键的**任务下沉(Task Sinking)**技术。

3.1 全图下沉机制

在传统的单算子执行模式下,每个算子都需要 Host 下发一次 Launch 指令。而在图模式下:

  • 拓扑映射:Runtime 接收 GE 编译好的离线模型,将其中的计算节点和通信节点映射为 NPU 内部的任务序列。
  • 一次下发,自主运行:Runtime 只需下发一次“执行图”的指令,随后的算子依赖、数据流转完全由 NPU 上的任务调度器(Task Scheduler)自动管理。

3.2 循环下沉(Loop Sinking)

针对训练场景中常见的 For Loop(如每个 Epoch 包含数千次迭代),Runtime 支持将循环控制逻辑也下沉到 Device 侧。

  • 硬件计数器:利用 NPU 上的标量处理单元维护循环计数。
  • 零交互:Host 仅需启动一次任务,Device 即可自动循环执行数千次 Step,直到满足退出条件。这种模式将 Host-Device 交互频率降低了几个数量级。

3.3 参数常驻与零拷贝

在图执行过程中,模型的权重(Weights)常驻 Device 内存。Runtime 通过智能的内存复用算法,确保在多次推理或训练迭代之间,权重数据不需要重复搬运,仅需更新输入数据(Input Feature Map)即可启动新一轮计算。

4. 上下文(Context)管理与多租户资源隔离

在多进程或多线程并发访问 NPU 的场景下,Runtime 必须保证资源的隔离性与安全性。Context 对象是这一机制的核心容器。

4.1 Context 的资源视图

一个 Context 代表了一个独立的设备执行环境。它包含:

  • Stream 句柄:属于该 Context 的所有流。
  • 内存映射表:该 Context 申请的设备虚拟地址(Device Virtual Address)到物理地址的页表映射。
  • 算子加载表:已加载到 Device 的二进制 Kernel 镜像。

4.2 线程绑定与栈管理

Runtime 采用线程局部存储(TLS)技术管理 Context 栈。

  • SetCurrentContext:当用户线程调用此接口时,Runtime 将指定的 Context 压入当前线程的栈顶。
  • 隐式切换:后续所有的 ACL API 调用(如内存申请、算子启动)都会自动关联到栈顶的 Context。这种设计使得多线程编程更加灵活,不同线程可以并发操作不同的 Device,或者协同操作同一个 Context。

4.3 进程间通信(IPC)与内存共享

虽然 Context 提供了隔离,但 Runtime 也支持跨进程的内存共享。通过 aclrtCreateIpcHandle,一个进程可以将某块 Device 内存导出为句柄,另一个进程通过 Runtime 接口导入该句柄,从而实现多个进程直接在 NPU 显存层面共享数据,无需经过 CPU 中转。

5. RAS 机制与全链路可观测性

在复杂的 AI 集群环境中,硬件故障或软件错误不可避免。Runtime 构建了完善的 RAS(Reliability, Availability, Serviceability)和维测体系。

5.1 异步异常回调

由于计算是异步的,当算子在 Device 侧发生错误(如除零、地址越界)时,Host 侧的主线程可能已经执行到了其他位置。

  • Callback 注册:Runtime 允许用户注册全局异常回调函数。
  • 错误报告:当 NPU 硬件捕获到异常中断时,驱动层会上报给 Runtime,Runtime 随即触发回调,提供出错的 Stream ID、Task ID 以及具体的硬件错误码(Device Error Code)。

5.2 黑匣子(Black Box)与 Core Dump

针对致命错误导致的系统崩溃,Runtime 实现了黑匣子机制。

  • 寄存器快照:在复位前,自动保存 AI Core 的 PC 指针、LR 寄存器和关键状态寄存器。
  • 死前日志:将最后时刻的内核日志(Kernel Log)刷入非易失存储器。这使得开发者可以在事后通过分析 Dump 文件,精确还原出错现场的指令流。

5.3 Profiling 数据通路

Runtime 内部集成了高性能的 Profiling 探针。

  • 硬件计数器(PMU):Runtime 能够配置并读取 NPU 的 PMU 单元,采集 Cache 命中率、Cube 单元利用率等微架构指标。
  • Task Trace:记录每个任务在 Device 上的精确开始和结束时间。这些数据通过专用的高速数据通路(TDT, Trusted Data Transmission)回传到 Host,供 MSPROFILER 工具生成可视化流水线图。
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐