Matmul高阶API使能IBShare性能提升案例
案例介绍
本案例呈现了在融合算子场景中,使用Matmul高阶API进行矩阵乘法计算时,A矩阵和B矩阵同时启用IBShare对性能的提升效果。
该案例的关键优化措施包括:
- 分核逻辑:以Cube核视角分核,Matmul计算结果输出到GM,提供给Vector核进行后续计算。
- 开启IBShare:A矩阵和B矩阵同时开启IBShare。
本案例的算子规格如下:
输入 |
Shape |
Data type |
Format |
---|---|---|---|
x |
128,384 |
float16 |
ND |
y |
384,256 |
float16 |
ND |
开启IBShare和未开启IBShare的完整样例请参考matmulABshare样例和MatmulNoABshare样例。
获取性能数据
使用MsProf工具获取算子的Profiling的数据,重点分析MTE2,Cube,Scalar的流水情况。
分析主要瓶颈点
图1 优化前Profiling数据


由以上Profiling数据,可以看出Scalar耗时占比较大,当前性能瓶颈点在于Scalar流水。优化前的执行多次的平均耗时为:27.06us。
设计优化方案
A矩阵和B矩阵均未开启IBShare时,数据需要根据K轴、M轴或N轴进行切分计算。
图2 未开启IBShare


当A矩阵和B矩阵都启用IBShare时,它们可以在L1 Buffer上复用,省去了切分、重复加载的过程,同时Cube计算单元完全由AIV0单核驱动,发起一次计算,计算的结果由AIV0和AIV1共享,从而减少Cube响应的次数,减少Scalar计算。
图3 开启IBShare
开启IBShare和不开启IBShare的消息交互对比示意图如下:
通过设置 B矩阵MatmulType的IBShare开关为true,开启IBShare,具体代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | constexpr bool isABshare = true; template <typename aType, typename bType, typename cType> class MatmutABshareKernel { public: __aicore__ inline MatmutABshareKernel(){}; __aicore__ inline void Init(GM_ADDR a, GM_ADDR b, GM_ADDR c, GM_ADDR workspace, const TCubeTiling &tiling, AscendC::TPipe *pipe); __aicore__ inline void Process(AscendC::TPipe *pipe); __aicore__ inline void CalcOffset(int32_t blockIdx, const TCubeTiling &tiling, int32_t &offsetA, int32_t &offsetB, int32_t &offsetC); Matmul<MatmulType<AscendC::TPosition::GM, CubeFormat::ND, aType, false, LayoutMode::NONE, isABshare>, MatmulType<AscendC::TPosition::GM, CubeFormat::ND, bType, false, LayoutMode::NONE, isABshare>, MatmulType<AscendC::TPosition::VECIN, CubeFormat::ND, cType>> matmulObj; AscendC::GlobalTensor<aType> aGlobal; AscendC::GlobalTensor<bType> bGlobal; AscendC::GlobalTensor<cType> cGlobal; TCubeTiling tiling; }; template <typename aType, typename bType, typename cType> __aicore__ inline void MatmutABshareKernel<aType, bType, cType>::Init(GM_ADDR a, GM_ADDR b, GM_ADDR c, GM_ADDR workspace,const TCubeTiling &tiling, AscendC::TPipe *pipe) { this->tiling = tiling; aGlobal.SetGlobalBuffer(reinterpret_cast<__gm__ aType *>(a), tiling.M * tiling.Ka); bGlobal.SetGlobalBuffer(reinterpret_cast<__gm__ bType *>(b), tiling.Kb * tiling.N); cGlobal.SetGlobalBuffer(reinterpret_cast<__gm__ cType *>(c), tiling.M * tiling.N); int32_t offsetA, offsetB, offsetC; CalcOffset(AscendC::GetBlockIdx(), tiling, offsetA, offsetB, offsetC); // calculate offset aGlobal = aGlobal[offsetA]; bGlobal = bGlobal[offsetB]; cGlobal = cGlobal[offsetC]; } template <typename aType, typename bType, typename cType> __aicore__ inline void MatmutABshareKernel<aType, bType, cType>::CalcOffset(int32_t blockIdx, const TCubeTiling &tiling, int32_t &offsetA, int32_t &offsetB, int32_t &offsetC) { offsetA = 0; offsetB = 0; offsetC = 0; } |
验证优化方案性能收益
优化后的执行多次的平均耗时:20.61us,较优化前有较大提升。
图4 优化后Profiling数据


总结
融合算子场景下,Matmul A矩阵和B矩阵同时开启IBShare,以Cube核视角分核,可以有效减少Cube侧的Scalar开销,提升性能。
父主题: 优秀实践