如章节所述,基于昇腾处理器的应用程序通常分为两部分:Host代码与Device代码。其中,Host代码运行在CPU上,负责设备资源管理、Host Memory与Device Memory数据搬运及任务调度等;Device代码运行在NPU(神经网络处理器)上,专门执行实际的计算任务。本编程指南重点讲解如何基于Ascend C编程语言编写Device代码,以及如何通过Host代码完成Device代码的调度与执行。
Device端的核心计算单元为AI Core,是昇腾AI处理器的核心算力载体。单枚昇腾NPU芯片通常集成多个AI Core,各核心可并行协作,大幅提升设备整体计算吞吐量。每个AI Core内部架构模块化、分工明确,核心组成组件如下:
标量处理单元:负责处理控制流(如分支、循环)和地址计算,功能类似传统CPU核心,是AI Core的“控制中枢”。
向量处理单元:承担核心向量运算任务,是SIMD、SIMT两种并行执行模型的主要硬件载体,不同昇腾硬件架构对两类并行模式的适配能力存在差异。
矩阵运算单元:针对矩阵乘加运算做深度硬件优化,仅支持SIMD执行模式,是深度学习卷积、全连接层等核心算子的极速加速单元。
本地存储:AI Core内置的高速存储资源,用于缓存实时计算所需数据,可有效规避全局Device Memory的高延迟访问问题,显著提升整体计算效率。
需重点区分架构差异:Ascend 950PR/Ascend 950DT架构之前的AI Core,仅支持SIMD单一执行模型;自Ascend 950PR/Ascend 950DT架构起,AI Core向量处理单元同时兼容SIMD、SIMT两种并行模型,可根据不同计算任务灵活选择并行方案,适配更多复杂业务场景。
[object Object]
在高性能并行编程领域,SIMD与SIMT是两类主流核心并行执行模型,定义了指令驱动多计算单元协同工作的核心机制,是提升程序数据吞吐量、优化计算性能的关键技术,也是Ascend C编程的核心学习内容。
核心概念:SIMD(Single Instruction Multiple Data)是一种 数据并行 模型,核心逻辑是:一条指令在同一个时钟周期内,对多个数据元素执行完全相同的操作,实现数据的批量并行处理。
核心特征:
- 单指令驱动:所有并行计算单元同步执行同一条指令,操作完全一致;
- 数据同构:要求参与计算的数据类型统一、长度相同,确保指令可批量处理;
- 同步执行:所有数据的操作在同一个指令周期内完成,无独立调度逻辑,执行节奏完全统一。
适用场景:主要适配数据密集、操作规整、无分支或分支极少的计算任务,典型场景包括:
- 图像像素处理(如灰度化、滤波、像素缩放);
- 音频信号分析(如降噪、信号预处理);
- 矩阵乘法、卷积等深度学习核心运算;
- 逐元素数学函数(如向量加减、乘除、指数/对数运算)。
SIMD编程四步法:SIMD编程遵循SPMD模型(Single Program Multiple Data, 单程序多数据),即每个AI Core运行同一份核函数,但负责处理不同的数据块,具体步骤如下:
- Tiling(分块)设计:对全局超大数据进行均匀切分,为各AI Core分配大小均衡的独立数据分片,精准适配SPMD多核并行架构,规避单核算力瓶颈,实现全域负载均衡。
- 数据搬入:调用SIMD专用API,将计算所需的数据从Device Memory(通常为HBM)搬运到AI Core的本地缓存,减少全局内存访问延迟。
- 数据计算:调用向量指令,一次处理多个同构数据;需注意,数据搬运与计算过程通常是异步执行的,需插入同步指令,确保计算时数据已就绪,保证结果准确。
- 数据搬出:调用SIMD专用API,将本地缓存中完成计算的结果,搬运回Device Memory,供后续任务使用。
核心概念:SIMT(Single Instruction Multiple Threads)是一种 线程并行 模型,核心逻辑是:一条指令同时驱动多个独立线程,每个线程仅处理一个数据元素;指令同步下发,但线程可根据代码分支(如 if-else)独立执行,灵活性更高。
核心特征:
- 单指令控制多线程:一条指令同步调度一组线程(如32个线程组成的Warp),统一发起执行指令;
- 线程独立:每个线程拥有独立的程序计数器、寄存器和执行状态,可单独处理一个数据元素,支持复杂分支逻辑;
- 硬件自动调度与掩蔽:线程的调度、切换,以及不活跃线程的掩蔽(Masking)均由硬件自动完成,无需程序员手动管理,降低开发复杂度。
适用场景:主要适配不规则数据访问、分支密集、稀疏计算等场景,典型场景包括:
- 深度学习中的稀疏算子(如稀疏卷积、稀疏矩阵运算);
- 带有复杂 if-else 分支的逐元素运算;
- 具有动态数据依赖的算法(如并行前缀和、排序网络)。
SIMT编程四步法:SIMT编程同样遵循SPMD模型,即同一份程序运行在每个线程上,每个线程处理不同的数据元素,具体步骤如下:
- Tiling(分块)设计:将整体任务拆分为多个独立线程,使线程索引与数据索引一一对应,确保每个线程处理唯一的数据元素,避免数据重复或遗漏。
- 数据搬入:通常通过指针直接访问Device Memory,无需调用SIMD那样的专用API;硬件会自动将所需数据从Device Memory加载到线程的寄存器中,简化开发流程。
- 数据计算:编程方式类似CPU标量代码,支持分支、循环等复杂控制逻辑;数据搬运与计算过程通常无需显式同步,若涉及多线程协作(如使用共享内存),需插入同步指令。
- 数据搬出:通常通过指针直接将计算结果写回Device Memory,无需调用专用API,与CPU编程逻辑更接近,降低上手难度。
[object Object]
结合AI Core硬件特性及上述两种并行模型,Ascend C为开发者提供了三种灵活的AI Core编程路径,可根据业务任务特性按需选择。其中,AI Core整机超过90%的计算吞吐量由SIMD并行机制承载,是释放硬件算力的核心路径,因此SIMD编程构成了AI Core的主导编程范式;SIMT编程则仅作用于部分特定场景,作为补充方案。
- 能力范围:支持向量计算、矩阵计算,以及向量与矩阵的融合计算,覆盖深度学习大部分核心场景;
- 适用场景:规整的、高密度的数据并行任务,如卷积、矩阵乘、逐元素变换等,是昇腾NPU开发的主流选择;
- 优势:能效比高,指令执行开销低,可充分发挥硬件性能,接近AI Core的峰值计算能力;
- 学习路径:详见;算子开发流程参见 。
- 能力范围:仅支持向量计算,不支持矩阵运算或向量与矩阵的融合计算,功能范围相对有限;
- 适用场景:离散数据访问、复杂分支控制的向量算子,同时适合熟悉SIMT模型的开发者快速上手 Ascend C;
- 限制:当前仅支持 Ascend 950PR/Ascend 950DT 芯片架构;
- 学习路径:详见;算子开发参见 。
SIMD与SIMT混合编程的Kernel,底层仍以SIMD编程模型为基础。开发者可在Kernel函数内部灵活组合两类编程逻辑:通过SIMT逻辑处理稀疏索引、复杂分支等不规则计算场景,输出规整化数据块;再通过SIMD高吞吐向量/矩阵运算处理规整数据,兼顾代码灵活性与硬件高性能,适配复杂混合计算场景。详细实现方法请参考。
Ascend C采用SIMD+SIMT双模并行的核心设计,既保留了SIMD高能效、高吞吐量的核心优势,又通过SIMT模型补齐了离散数据、复杂分支等不规则场景的计算能力,实现全场景计算任务的高效适配。开发者在实际开发中,可根据算法的访存模式(连续规整/离散随机)、分支密度(低分支/高分支)及并行粒度,灵活选用单一编程模型或混合编程方案。此外,Host侧通过CANN Runtime API提供内存管理、任务调度等能力,与Device侧代码协同工作,共同实现异构计算的高效运行。
[object Object]
AI CPU是Device上的辅助处理器(基于 ARM 架构),主要用于执行一些无法由AI Core高效处理的任务,例如:控制流复杂、数据依赖强的逻辑等。其编程模型遵循通用CPU编程规范,采用标准C/C++语法即可开发。详细开发指南请阅读。