Matmul高阶API使能UnitFlag

案例介绍

本案例呈现了在矩阵乘算子场景中,使用Matmul高阶API进行矩阵乘法计算,使能UnitFlag功能对算子性能的提升效果。UnitFlag功能为AIC核中MMAD计算指令和FIXPIPE数据搬运指令提供了基于内存访问的细粒度同步,使计算与搬运流水并行。使能UnitFlag功能的方式为将MatmulConfig中的enUnitFlag参数设置为true。enUnitFlag参数的详细介绍请参考MatmulConfig

本案例的算子规格如下:

表1 算子规格

输入

Shape

Data type

Format

a

128, 64

float16

ND

b

64, 30720

float16

ND

当前案例使用的AI处理器共20个核,每个核包含1个AIC核和2个AIV核。

算子的Tiling参数如下:

获取性能数据

使用msProf工具获取算子仿真流水图上板Profiling数据。因为UnitFlag功能主要优化MMAD和FIXPIPE流水串行问题,所以获取性能数据后重点分析Cube、FIXPIPE的流水情况。

分析主要瓶颈点

设计优化方案

如下图所示,未开启UnitFlag功能时,MMAD和FIXPIPE是指令级别的同步,FIXPIPE指令需要等MMAD指令执行完成才进行结果搬出,MMAD和FIXPIPE之间流水串行。

图1 未开启UnitFlag功能

如下图所示,开启UnitFlag功能时,MMAD和FIXPIPE指令是512B大小的细粒度同步。在一条MMAD指令执行过程中,每当完成一个512B数据结果的计算,FIXPIPE立即开始搬出该512B的数据,从而实现MMAD和FIXPIPE之间的流水并行,提升算子性能。

图2 开启UnitFlag功能

Matmul API使能UnitFlag功能的完整样例请参考Matmul API性能优化样例。使能UnitFlag功能的主要步骤如下:

  1. 自定义MatmulConfig模板参数,将其中的enUnitFlag参数设置为true,使能UnitFlag功能。

    1
    2
    3
    4
    5
    6
    7
    __aicore__ inline constexpr MatmulConfig GetCustomMDLCFG()
    {
        auto mmCfg = CFG_MDL;
        mmCfg.enUnitFlag = true;
        return mmCfg;
    }
    constexpr static MatmulConfig CUSTOM_CFG_MDL = GetCustomMDLCFG();
    

  2. 基于自定义的MatmulConfig模板参数,创建Matmul对象。

    1
    2
    3
    4
    5
    using A_TYPE = AscendC::MatmulType<AscendC::TPosition::GM, CubeFormat::ND, AType>;
    using B_TYPE = AscendC::MatmulType<AscendC::TPosition::GM, CubeFormat::ND, BType>;
    using C_TYPE = AscendC::MatmulType<AscendC::TPosition::GM, CubeFormat::ND, CType>;
    using BIAS_TYPE =  AscendC::MatmulType<AscendC::TPosition::GM, CubeFormat::ND, BiasType>;
    AscendC::Matmul<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, CUSTOM_CFG_MDL > matmulObj;
    

验证优化方案性能收益

总结

在算子的MMAD计算流水和FIXPIPE数据搬出流水串行且未被其他流水掩盖(比如MTE2 Bound)时,考虑使能UnitFlag功能,实现MMAD计算流水和FIXPIPE数据搬出流水的流水并行,提升算子性能。