昇腾社区首页
中文
注册

Matmul高阶API使能MTE2 Preload

案例介绍

本案例呈现了在矩阵乘算子场景中,使用Matmul高阶API进行矩阵乘法计算,使能MTE2 Preload对算子性能的提升效果通过MatmulConfig中的doMTE2Preload参数开启矩阵M/N方向的预加载功能,预加载即在MTE2间隙提前加载A矩阵/B矩阵数据,开启预加载功能后,可以减少MET2间隙,提升算子性能。doMTE2Preload参数的详细介绍请参考MatmulConfig

  • 使能MTE2 Preload的适用场景

    MTE2流水间隙较大,且M或N数值较大时。

  • 使能MTE2 Preload的约束条件
    • 仅在使用MDL模板和SpecialMDL模板时,MTE2 Preload有效。
    • 开启M或N方向预加载功能时,需保证K方向数据全载,且M或N方向开启DoubleBuffer。
    • K方向数据全载的条件是singleK <= baseK * stepK。
    • M方向开启DoubleBuffer的条件是depthA1 = stepM * stepK * 2。
    • N方向开启DoubleBuffer的条件是depthB1 = stepN * stepK * 2。

本案例的算子规格如下:

表1 算子规格

输入

Shape

Data type

Format

a

128, 512

float16

ND

b

512, 24576

float16

ND

当前案例使用的AI处理器共24个核,算子中使能高阶API Matmul的纯Cube模式。使用MDL模板,Tiling参数如下:

  • 原始shape:M=128, N= 24576, K=512。
  • 单核shape:singleCoreM=128,singleCoreN=1024,singleCoreK=512。
  • 基本块shape:baseM=128,baseN=128,baseK=64。
  • L1缓存相关Tiling参数:stepM=1,stepN=1,stepKa=8,stepKb=8,depthA1=8,depthB1=16。

获取性能数据

使用msProf工具获取算子仿真流水图上板Profiling数据,重点分析Cube,Fixpipe的流水情况。

分析主要瓶颈点

  • 优化前的流水图如下,M和K方向全载,因此A矩阵只搬运一次。由于N较大,B矩阵会搬运多次,可以看到单次MTE2间存在间隙。
  • 优化前的Profiling数据如下,aic_time平均耗时30.88us。

设计优化方案

使能MTE2 Preload功能:在创建Matmul对象时,开启doMTE2Preload开关。具体步骤如下:

  1. 配置MDL模板参数,将其中的doMTE2Preload参数设置为2,使能N方向Preload功能。
    1
    2
     // preloadMode = 2
    static constexpr MatmulConfig MM_CFG = GetMDLConfig(false, false, preloadMode); 
    
  2. 基于自定义MatmulConfig模板参数,创建Matmul对象。
    1
    2
    3
    4
    AscendC::Matmul<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>, MM_CFG> matmulObj;
    

验证优化方案性能收益

  • 优化后的流水图如下,Tiling参数不变,可以看到,下一次计算使用的B矩阵数据提前加载,MTE2间的间隙缩短。
  • 优化后的Profiling数据如下,aic_time平均耗时28.50us,较优化前的30.88us有所提升。

总结

当MTE2流水间隙较大,且M或N数值较大时,可以考虑使能MTE2 Preload功能,提前加载A矩阵或B矩阵数据。