本案例呈现了在矩阵乘算子场景中,使用Matmul高阶API进行矩阵乘法计算,使能NBuffer33模板对算子性能的提升效果。NBuffer33模板的实现为单核计算的A矩阵切分为3x3个基本块,该3x3个A矩阵的基本块全载和保持在L1 Buffer中,每次与3x1个B矩阵的基本块计算矩阵乘,同时DoubleBuffer并行搬入下次计算所需的3x1个B矩阵基本块,直到singleCoreN方向的矩阵乘计算完成。针对MTE2 Bound场景,通过NBuffer33算法的切分数据方式,错开搬运流水,减少单次搬运的数据量,平衡MTE2和FixPipe的数据流量,让两者带宽均匀分布。NBuffer33模板的详细介绍请参考MatmulPolicy。
本案例的算子规格如下:
|
输入 |
Shape |
Data type |
Format |
|---|---|---|---|
|
a |
256, 192 |
float16 |
ND |
|
b |
192, 512 |
float16 |
ND |
当前案例使用的AI处理器共24个核,算子中使能高阶API Matmul的纯Cube模式,使用MDL模板,Tiling参数如下:
使用msProf工具获取算子仿真流水图和上板Profiling数据,重点分析Cube、Fixpipe的流水情况。
使能NBuffer33模板:在GetTiling接口前,调用SetMatmulConfigParams接口开启NBuffer33模式,使获取的Tiling满足要求;Kernel侧在创建Matmul对象时使能NBuffer33模板。使能NBuffer33模板的完整样例请参考使能NBuffer33模板策略的样例。具体步骤如下:
1 2 3 4 5 6 7 8 |
matmul_tiling::MatmulConfigParams matmulConfigParams(1, false, matmul_tiling::ScheduleType::N_BUFFER_33, /* NBuffer33模式 */ matmul_tiling::MatrixTraverse::NOSET, false); cubeTiling.SetMatmulConfigParams(matmulConfigParams); if (cubeTiling.GetTiling(tilingData) == -1) { std::cout << "Generate tiling failed." << std::endl; return {}; } |
1 2 3 4 5 6 7 |
AscendC::MatmulImpl< AscendC::MatmulType<AscendC::TPosition::GM, CubeFormat::ND, aType>, AscendC::MatmulType<AscendC::TPosition::GM, CubeFormat::ND, bType>, AscendC::MatmulType<AscendC::TPosition::GM, CubeFormat::ND, cType>, AscendC::MatmulType<AscendC::TPosition::GM, CubeFormat::ND, biasType>, CFG_MDL, AscendC::MatmulCallBackFunc<nullptr, nullptr, nullptr>, AscendC::Impl::Detail::NBuffer33MatmulPolicy> matmulObj; |
MTE2 Bound的场景,Tiling参数满足stepM、stepKa、stepKb小于等于3的条件时,可以考虑使能NBuffer33模板,切分矩阵将搬运流水错开, 减少单次搬运的数据量,平衡MTE2和FixPipe的数据流量。