Matmul 多核对齐切分完整指南:从切分策略到核数配置
2026/8/21 17:52:15 网站建设 项目流程

Matmul 多核对齐切分完整指南:从切分策略到核数配置

【免费下载链接】asc-devkit本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C++标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。项目地址: https://gitcode.com/cann/asc-devkit

CANN asc-devkit 面向昇腾 AI 处理器的算子开发,其 Matmul 高阶 API 提供了MultiCoreMatmulTiling这一多核矩阵乘 Tiling 对象,用于把大矩阵合理地分配到多个核上并行计算。这篇文章将带大家弄清多核对齐切分的两种策略、Tiling 参数的含义,以及SetDimSetBlockDim的正确用法,最后给出可直接套用的代码模板。

为什么多核场景必须做矩阵切分

单核处理的性能瓶颈

一次完整的矩阵乘C(M,N) = A(M,K) × B(K,N)需要 M×N×K 量级的乘加运算。在单核上顺序执行时,核内存储空间有限、计算单元空闲率偏高,数据量一大就很容易成为整个算子的性能短板。因此,要提升计算效率,最直接的手段就是让多个核同时参与计算。

多核并行的核心思路

多核并行的前提,是把大矩阵切成若干独立的分块,每个核只处理属于自己的那部分数据。切分后的每个分块大小(即单核负载)会被记录到 Tiling 参数中,例如SingleCoreMSingleCoreNSingleCoreK。这些参数是设备侧 Kernel 拿到多少数据、按什么尺寸搬移和计算的依据,也是多核场景与单核场景在 Tiling 阶段的本质区别。

两种主流切分策略拆解

按照是否切分 K 轴,多核对齐切分分为两种策略。不同策略决定了分块在核间的分布方式,也直接影响累加逻辑的写法。

不切分 K 轴:沿 M、N 轴分块

这种策略只切 M、N 两个维度,K 维度保持完整,具体划分如下:

  • A 矩阵:沿 M 轴切分,得到若干份大小为SingleCoreM × K的分块;
  • B 矩阵:沿 N 轴切分,得到若干份大小为K × SingleCoreN的分块;
  • C 矩阵:单核上由SingleCoreM × K的 A 分块与K × SingleCoreN的 B 分块相乘,直接得到SingleCoreM × SingleCoreN的 C 分块。

举例来说,若有 8 个核参与计算,把 A 沿 M 轴切成 4 块、B 沿 N 轴切成 2 块,就得到 4×2 的核间网格。每个核只需要加载自己那一份 A 分块和 B 分块,例如某个核仅处理绿色标记的数据,其输出就是对应位置SingleCoreM × SingleCoreN的 C 分块。

切分 K 轴:M、N、K 三轴联合分块

当单核的存储放不下完整 K 维数据,或者希望进一步提高并行度时,可以对三个轴同时切分:

  • A 矩阵:沿 M 轴切成SingleCoreM,沿 K 轴切成SingleCoreK,单核处理SingleCoreM × SingleCoreK的数据;
  • B 矩阵:沿 K 轴切成SingleCoreK,沿 N 轴切成SingleCoreN,单核处理SingleCoreK × SingleCoreN的数据;
  • C 矩阵:每个 C 分块不再由一次乘法得到,而是A1×B1 + A2×B2 + A3×B3这样的累加结果。

以切分成 3 份 K 块为例,C 矩阵中的某个 R 块需要通过 A1×B1、A2×B2、A3×B3 三组乘积累加得到。这三组乘法互相独立,恰好可以分配到不同的核上并行执行,之后再把部分和累加回 C 分块。

两种策略如何选择

如果 K 维相对较小、单核放得下整段 K 数据,优先选择不切 K 轴的方案,累加逻辑简单、代码更易维护;如果 K 很大或核数很多、需要更大并行度,则选择三轴切分方案。需要留意的是,切 K 轴会引入跨核的部分和累加,通常需要额外的同步或归约处理。

关键参数与核数设置规则

Tiling 参数的含义

SingleCoreMSingleCoreNSingleCoreK是切分结果的直接体现,分别表示单核上处理的 M、N、K 维度尺寸。host 侧通过调用MultiCoreMatmulTiling的接口自动计算并获取这些参数,无需手动推算。它们会随算子的输入形状、可用核数自动调整,属于“声明形状后自动算好”的参数。

SetDim 与 SetBlockDim 的分工

多核 Tiling 中有一个容易混淆的点:SetDimSetBlockDim各自负责什么。

  • SetDim:设置 Matmul 计算可用的核数,仅在多核场景下使用,用于驱动 Tiling 参数的计算,即告诉 Tiling 对象“有多少核可以参与矩阵乘”;
  • SetBlockDim:设置整个算子计算所用核数,即实际会被加载执行的核数,这个值是必须设置的,规则与numBlocks的说明一致。

在纯 Cube 模式(只有矩阵计算)下,典型做法是先用SetDim把当前 AI 处理器上可用的 Cube 核数传入,再通过GetTiling得到 Matmul 实际使用的核数,该值会小于等于可用的核数。随后用户按实际使用的核数配置SetBlockDim。若算子还包含矢量计算(MIX 模式),核数设置规则会更复杂,需要参考 MIX 场景核数设置规则单独处理。

需要注意的约束

本场景没有额外限制条件,只要遵循上述设置顺序即可:先构造 Tiling 对象并设置维度与类型,再设置核数,最后获取 Tiling 参数。注意GetTiling的返回值用于判断是否成功,返回 -1 表示 Tiling 生成失败。

调用示例与关键步骤解读

以纯 Cube 模式的浮点矩阵乘为例,下面这段代码展示了多核 Tiling 的完整调用流程,可以分为三步理解。

第一步:构造多核 Tiling 对象

首先根据 SoC 版本获取平台实例,并以此构造MultiCoreMatmulTiling对象。与单核场景不同,多核必须使用该类而不是普通 Tiling 对象,否则无法获取多核相关的切分参数。

// 构造多核Tiling对象 auto ascendcPlatform = platform_ascendc::PlatformAscendCManager::GetInstance(socVersion); matmul_tiling::MultiCoreMatmulTiling cubeTiling(*ascendcPlatform); // 仅包含Cube计算的算子,设置可参与矩阵乘运算的核数为当前AI处理器上的Cube核数 cubeTiling.SetDim(ascendcPlatform.GetCoreNumAic());

这里通过GetCoreNumAic()拿到当前 AI 处理器上的 Cube 核数并传给SetDim,相当于告诉 Tiling 对象“最多可以用这么多核”。

第二步:声明矩阵类型与形状

接着分别声明 A、B、C 三个矩阵以及偏置在全局内存中的位置、格式与数据类型,并传入原始的 M、N、K 形状。是否需要偏置由EnableBias控制。

cubeTiling.SetAType(matmul_tiling::TPosition::GM, matmul_tiling::CubeFormat::ND, matmul_tiling::DataType::DT_FLOAT16); cubeTiling.SetBType(matmul_tiling::TPosition::GM, matmul_tiling::CubeFormat::ND, matmul_tiling::DataType::DT_FLOAT16); cubeTiling.SetCType(matmul_tiling::TPosition::GM, matmul_tiling::CubeFormat::ND, matmul_tiling::DataType::DT_FLOAT); cubeTiling.SetBiasType(matmul_tiling::TPosition::GM, matmul_tiling::CubeFormat::ND, matmul_tiling::DataType::DT_FLOAT); cubeTiling.SetOrgShape(M, N, K); cubeTiling.SetShape(M, N, K); cubeTiling.EnableBias(isBias);

第三步:获取 Tiling 参数

最后把结果写入TCubeTiling结构体,并检查返回值。拿到 tilingData 后,后续即可据此为设备侧 Kernel 计算地址偏移、循环边界等运行时信息。

optiling::TCubeTiling tilingData; // 获取Tiling参数 int ret = cubeTiling.GetTiling(tilingData); // if ret = -1, gen tiling failed

小结

多核对齐切分的本质,是把大矩阵按 M、N、K 三个维度切分到多个核上并行计算。不切 K 轴时逻辑简单、适合 K 较小的场景;切 K 轴时并行度更高,但需要处理跨核的部分和累加。在实际编码中,牢记三点即可少走弯路:多核场景务必使用MultiCoreMatmulTilingSetDim决定“最多可用多少核”,SetBlockDim决定“实际加载多少核”,后者必须设置;最后用GetTiling的返回值确认 Tiling 是否生成成功。

【免费下载链接】asc-devkit本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C++标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。项目地址: https://gitcode.com/cann/asc-devkit

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询