本案例呈现了在矩阵乘算子场景中,使能Matmul高阶API的纯Cube模式对算子性能的提升效果。如下图所示,Matmul API默认使用MIX模式,即用户从AIV侧发起消息,通过消息通信框架中转消息后,在AIC侧执行Matmul计算。这套消息处理机制会带来额外的Scalar性能开销。相较于MIX模式,纯Cube模式可以直接跳过消息通信框架,完成Matmul计算,提升算子性能。
|
输入 |
Shape |
Data type |
Format |
|---|---|---|---|
|
a |
128, 64 |
float16 |
ND |
|
b |
64, 30720 |
float16 |
ND |
当前案例使用的AI处理器共24个核,每个核中包含1个AIC核和2个AIV核。
Tiling参数如下:
使用msProf工具获取算子仿真流水图和上板Profiling数据。因为纯Cube模式主要优化Scalar流水性能,可以重点分析Scalar的流水情况。
默认MIX模式下,用户在AIV侧发起消息,通过消息通信框架中转消息后,在AIC侧执行Matmul计算。基于这样的流程,用户使用Matmul高阶API编写算子代码时,可以使用REGIST_MATMUL_OBJ宏,无需区分AIV和AIC,但也因这套消息处理机制导致产生了额外的性能开销,如图1 默认MIX模式的Matmul流程示意图所示。
实现默认MIX模式的具体步骤如下:
1 2 3 4 5 6 7 |
#include "lib/matmul_intf.h" 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, CFG_NORM> matmulObj; |
1 2 3 4 |
auto ascendcPlatform = platform_ascendc::PlatformAscendCManager::GetInstance(); matmul_tiling::MultiCoreMatmulTiling cubeTiling(*ascendcPlatform); int32_t numBlocks = ascendcPlatform->GetCoreNumAiv(); // MIX模式使用GetCoreNumAiv获取AI处理器可用的核数。 cubeTiling.SetDim(numBlocks); |
1
|
matmul_custom_do(ascendcPlatform->GetCoreNumAic(), stream, x1, x2, bias, y, workspaceDevice, tilingDevice); // MIX模式下,启动时,按照AIV和AIC组合启动,numBlocks用于设置启动多少个AI Core。 |
在没有矢量计算的算子场景下,可以跳过消息通信框架的机制,使能纯Cube模式完成Matmul计算,减少消息通信的性能开销,提升算子性能。
Matmul API使能纯Cube模式的完整样例请参考Matmul API性能优化样例。使能纯Cube模式的主要步骤如下:
1 2 3 4 5 6 7 8 |
#define ASCENDC_CUBE_ONLY // 在#include "lib/matmul_intf.h"前,设置ASCENDC_CUBE_ONLY宏 #include "lib/matmul_intf.h" 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, CFG_NORM> matmulObj; |
1 2 3 4 |
auto ascendcPlatform = platform_ascendc::PlatformAscendCManager::GetInstance(); matmul_tiling::MultiCoreMatmulTiling cubeTiling(*ascendcPlatform); int32_t numBlocks = ascendcPlatform->GetCoreNumAic(); // 纯Cube模式使用GetCoreNumAic接口获取AI处理器可用的核数。 cubeTiling.SetDim(numBlocks); |
1
|
matmul_custom_do(ascendcPlatform->GetCoreNumAic(), stream, x1, x2, bias, y, workspaceDevice, tilingDevice); // 仅包含Cube计算的算子,numBlocks用于设置启动多少个AIC。 |
1 2 3 4 5 6 7 8 9 |
extern "C" __global__ __aicore__ void matmul_custom(GM_ADDR a, GM_ADDR b, GM_ADDR bias, GM_ADDR c, GM_ADDR workspace, GM_ADDR tilingGm) { if (g_coreType == AscendC::AIV) { // 纯Cube模式,AIV侧直接return return; } ... // 其他代码 } |
在只有矩阵计算,没有矢量计算的场景下,可以考虑使能纯Cube模式,优化Matmul计算中的消息通信性能开销,提升算子性能。