SWAT(Slide Window Adaptive Template)特性介绍【免费下载链接】cann-samples算子领域高性能实战演进样例与体系化调优知识库项目地址: https://gitcode.com/cann/cann-samples1. 原理介绍1.1 背景在性能优化过程中提升数据搬运效率的关键在于提高L2缓存的命中率。初始搬运阶段由于数据尚未加载至L2缓存无法利用缓存进行快速存取导致该阶段L2命中率较低搬运速度相对缓慢。随着搬运轮次的增加数据逐步被缓存重复搬运时的L2命中率显著提升搬运效率也随之提高。然而这种搬运效率的分布不均导致早期若干轮次中出现MMAD等待搬运流水的情况造成计算资源闲置制约了系统性能的进一步提升。针对上述问题本文引入SWATSlide Window Adaptive Template滑窗模板旨在通过自适应窗口机制优化搬运过程均衡流水负载从而提升整体性能。1.2 原理SWAT滑窗模板的核心思想是通过自适应滑动窗口机制优化多核计算中的数据排布与搬运顺序从而提升L2缓存的命中率均衡流水负载。具体而言SWAT将多核计算中每一轮迭代的输出数据按照固定的方正尺寸进行排布形成规整的数据块网格。在此基础上设定一个固定大小的滑动窗口以Z字形顺序在数据网格上滑动访问。原理图如下如图所示相较于传统的列优先匹配搬运方式SWAT滑窗模板的流水分布更加均匀有效减少了计算资源的闲置时间整体搬运效率显著提升。2. 实践使用swat优化matmul计算性能2.1 代码以一个典型的MatMul计算为例修改以下代码可实现swat效果// 初始化swat变量 static constexpr uint64_t WINDOW_LEN 4UL; uint64_t mainWindow WINDOW_LEN mTileNum ? WINDOW_LEN : mTileNum; uint64_t mainRow mTileNum / mainWindow - 1; uint64_t tailWindow mTileNum - mainRow * mainWindow; constexpr int64_t ROWS_PER_CYCLE 2; // 多核计算逻辑 for (uint64_t tileIdx curBlockIdx; tileIdx tileNum; tileIdx blockNum) { // SWAT将线性tile索引映射到二维(mTileIdx, nTileIdx)网格。 // 先完整处理主窗口行再处理尾窗口。 // 在奇数行反转nTileIdx采用蛇形顺序以提高缓存效率。 int64_t rowIdx tileIdx / nTileNum / mainWindow; if (rowIdx mainRow) { mTileIdx rowIdx * mainWindow tileIdx % mainWindow; nTileIdx (tileIdx / mainWindow) % nTileNum; } else { rowIdx mainRow; int64_t tailIndex tileIdx - mainRow * mainWindow * nTileNum; mTileIdx mainRow * mainWindow tailIndex % tailWindow; nTileIdx (tailIndex / tailWindow) % nTileNum; } if (rowIdx % ROWS_PER_CYCLE ! 0) { nTileIdx nTileNum - 1 - nTileIdx; } int64_t curM mTileIdx (mTileNum - 1) ? tailBaseM : baseM; int64_t curN nTileIdx (nTileNum - 1) ? tailBaseN : baseN; // 单核计算逻辑 ... }为避免尾轮尺寸小于滑窗尺寸导致滑窗形状不规整、无法实现最优分配将尾轮与次尾轮的基本块合并后统一进行滑窗分配顺序并重新计算滑窗长度。以核数为 28 为例滑窗分核逻辑示意图如下关键改动点:引入SWAT滑窗机制重构 mTileIdx 与 nTileIdx 的计算逻辑实现滑动窗口效果同时通过在奇数行对 nTileIdx 进行反转完成Z字形滑动访问提升缓存局部性。3. 性能结果对比3.1 case前后性能以基础MatMul算子为例在相同输入规模M1024, K1024, N8192下进行性能测试通过Profiling工具采集硬件流水线执行状态。从优化效果来看采用 SWAT 机制后原先因首轮 L2 命中率较低导致数据搬运效率下降进而引发搬运时间过长、打断后续 MMA 计算流水的问题得到了有效改善。SWAT 优化显著提升了首轮数据搬运效率使计算流水保持连续算子整体计算时间明显缩短。4. 结论适用场景大数据量矩阵乘法运算需要多次搬运数据缓存局部性对性能影响显著。列优先访问模式受限的场景传统列优先搬运导致早期流水线等待严重通过Z字形滑窗可平滑搬运负载分布。SWAT滑窗模板通过Z字形自适应窗口访问机制优化多核计算中的数据排布与搬运顺序显著提升L2缓存命中率均衡流水负载在数据量较大且重复访问频繁的计算场景下可有效减少搬运等待时间提升整体计算性能。5. 编译 执行编译样例从项目根目录启动构建参考项目README.md在仓库根目录下完成编译和安装后进入当前样例目录cmake -S . -B build -DNPU_ARCHdav-3510 cmake --build build --parallel cmake --install build --prefix ./build_out cd ./build_out/1_Features/memory_optimization/swat/如需单独编译当前样例可使用以下指令cmake --build build --target swat cp ./Samples/1_Features/memory_optimization/slide_window_adaptive_template/scripts/profile_matmul.py ./build/Samples/1_Features/memory_optimization/slide_window_adaptive_template/ cd ./build/Samples/1_Features/memory_optimization/slide_window_adaptive_template/运行样例使用可执行文件直接执行算子用例需要指定矩阵乘维度并随机生成输入数据。./swat 1024 2048 4096打印如下执行结果证明样例执行成功。matmul run successfully!如果存在精度问题则会打印错误数据并显示如下结果。matmul run failed!测试性能 运行性能测试脚本指定矩阵乘法的维度后执行。python3 profile_matmul.py 1024 2048 4096打印如下执行结果证明样例性能测试成功。[Profile Breakdowm] --------------------------------------------------------------------------------------------- | candidate | kernel(us) | mac(us) | scalar(us) | mte1(us) | mte2(us) | fixpipe(us) | icache_miss(%) | | swat | 49.738 | 40.524 | 2.727 | 12.922 | 33.809 | 1.976 | 1.200 | ---------------------------------------------------------------------------------------------与相同规模下的基础 MatMul 算子开启 double-buffer对比[Profile Breakdowm] --------------------------------------------------------------------------------------------- | candidate | kernel(us) | mac(us) | scalar(us) | mte1(us) | mte2(us) | fixpipe(us) | icache_miss(%) | | n_buffer | 66.000 | 40.810 | 2.558 | 10.659 | 37.595 | 1.980 | 1.200 | ---------------------------------------------------------------------------------------------可以看到由于整体的MTE2搬运效率提升整体计算时间缩短性能有所提升。6. 支持架构NPU ARCH 3510【免费下载链接】cann-samples算子领域高性能实战演进样例与体系化调优知识库项目地址: https://gitcode.com/cann/cann-samples创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
CANN滑窗自适应模板优化
SWAT(Slide Window Adaptive Template)特性介绍【免费下载链接】cann-samples算子领域高性能实战演进样例与体系化调优知识库项目地址: https://gitcode.com/cann/cann-samples1. 原理介绍1.1 背景在性能优化过程中提升数据搬运效率的关键在于提高L2缓存的命中率。初始搬运阶段由于数据尚未加载至L2缓存无法利用缓存进行快速存取导致该阶段L2命中率较低搬运速度相对缓慢。随着搬运轮次的增加数据逐步被缓存重复搬运时的L2命中率显著提升搬运效率也随之提高。然而这种搬运效率的分布不均导致早期若干轮次中出现MMAD等待搬运流水的情况造成计算资源闲置制约了系统性能的进一步提升。针对上述问题本文引入SWATSlide Window Adaptive Template滑窗模板旨在通过自适应窗口机制优化搬运过程均衡流水负载从而提升整体性能。1.2 原理SWAT滑窗模板的核心思想是通过自适应滑动窗口机制优化多核计算中的数据排布与搬运顺序从而提升L2缓存的命中率均衡流水负载。具体而言SWAT将多核计算中每一轮迭代的输出数据按照固定的方正尺寸进行排布形成规整的数据块网格。在此基础上设定一个固定大小的滑动窗口以Z字形顺序在数据网格上滑动访问。原理图如下如图所示相较于传统的列优先匹配搬运方式SWAT滑窗模板的流水分布更加均匀有效减少了计算资源的闲置时间整体搬运效率显著提升。2. 实践使用swat优化matmul计算性能2.1 代码以一个典型的MatMul计算为例修改以下代码可实现swat效果// 初始化swat变量 static constexpr uint64_t WINDOW_LEN 4UL; uint64_t mainWindow WINDOW_LEN mTileNum ? WINDOW_LEN : mTileNum; uint64_t mainRow mTileNum / mainWindow - 1; uint64_t tailWindow mTileNum - mainRow * mainWindow; constexpr int64_t ROWS_PER_CYCLE 2; // 多核计算逻辑 for (uint64_t tileIdx curBlockIdx; tileIdx tileNum; tileIdx blockNum) { // SWAT将线性tile索引映射到二维(mTileIdx, nTileIdx)网格。 // 先完整处理主窗口行再处理尾窗口。 // 在奇数行反转nTileIdx采用蛇形顺序以提高缓存效率。 int64_t rowIdx tileIdx / nTileNum / mainWindow; if (rowIdx mainRow) { mTileIdx rowIdx * mainWindow tileIdx % mainWindow; nTileIdx (tileIdx / mainWindow) % nTileNum; } else { rowIdx mainRow; int64_t tailIndex tileIdx - mainRow * mainWindow * nTileNum; mTileIdx mainRow * mainWindow tailIndex % tailWindow; nTileIdx (tailIndex / tailWindow) % nTileNum; } if (rowIdx % ROWS_PER_CYCLE ! 0) { nTileIdx nTileNum - 1 - nTileIdx; } int64_t curM mTileIdx (mTileNum - 1) ? tailBaseM : baseM; int64_t curN nTileIdx (nTileNum - 1) ? tailBaseN : baseN; // 单核计算逻辑 ... }为避免尾轮尺寸小于滑窗尺寸导致滑窗形状不规整、无法实现最优分配将尾轮与次尾轮的基本块合并后统一进行滑窗分配顺序并重新计算滑窗长度。以核数为 28 为例滑窗分核逻辑示意图如下关键改动点:引入SWAT滑窗机制重构 mTileIdx 与 nTileIdx 的计算逻辑实现滑动窗口效果同时通过在奇数行对 nTileIdx 进行反转完成Z字形滑动访问提升缓存局部性。3. 性能结果对比3.1 case前后性能以基础MatMul算子为例在相同输入规模M1024, K1024, N8192下进行性能测试通过Profiling工具采集硬件流水线执行状态。从优化效果来看采用 SWAT 机制后原先因首轮 L2 命中率较低导致数据搬运效率下降进而引发搬运时间过长、打断后续 MMA 计算流水的问题得到了有效改善。SWAT 优化显著提升了首轮数据搬运效率使计算流水保持连续算子整体计算时间明显缩短。4. 结论适用场景大数据量矩阵乘法运算需要多次搬运数据缓存局部性对性能影响显著。列优先访问模式受限的场景传统列优先搬运导致早期流水线等待严重通过Z字形滑窗可平滑搬运负载分布。SWAT滑窗模板通过Z字形自适应窗口访问机制优化多核计算中的数据排布与搬运顺序显著提升L2缓存命中率均衡流水负载在数据量较大且重复访问频繁的计算场景下可有效减少搬运等待时间提升整体计算性能。5. 编译 执行编译样例从项目根目录启动构建参考项目README.md在仓库根目录下完成编译和安装后进入当前样例目录cmake -S . -B build -DNPU_ARCHdav-3510 cmake --build build --parallel cmake --install build --prefix ./build_out cd ./build_out/1_Features/memory_optimization/swat/如需单独编译当前样例可使用以下指令cmake --build build --target swat cp ./Samples/1_Features/memory_optimization/slide_window_adaptive_template/scripts/profile_matmul.py ./build/Samples/1_Features/memory_optimization/slide_window_adaptive_template/ cd ./build/Samples/1_Features/memory_optimization/slide_window_adaptive_template/运行样例使用可执行文件直接执行算子用例需要指定矩阵乘维度并随机生成输入数据。./swat 1024 2048 4096打印如下执行结果证明样例执行成功。matmul run successfully!如果存在精度问题则会打印错误数据并显示如下结果。matmul run failed!测试性能 运行性能测试脚本指定矩阵乘法的维度后执行。python3 profile_matmul.py 1024 2048 4096打印如下执行结果证明样例性能测试成功。[Profile Breakdowm] --------------------------------------------------------------------------------------------- | candidate | kernel(us) | mac(us) | scalar(us) | mte1(us) | mte2(us) | fixpipe(us) | icache_miss(%) | | swat | 49.738 | 40.524 | 2.727 | 12.922 | 33.809 | 1.976 | 1.200 | ---------------------------------------------------------------------------------------------与相同规模下的基础 MatMul 算子开启 double-buffer对比[Profile Breakdowm] --------------------------------------------------------------------------------------------- | candidate | kernel(us) | mac(us) | scalar(us) | mte1(us) | mte2(us) | fixpipe(us) | icache_miss(%) | | n_buffer | 66.000 | 40.810 | 2.558 | 10.659 | 37.595 | 1.980 | 1.200 | ---------------------------------------------------------------------------------------------可以看到由于整体的MTE2搬运效率提升整体计算时间缩短性能有所提升。6. 支持架构NPU ARCH 3510【免费下载链接】cann-samples算子领域高性能实战演进样例与体系化调优知识库项目地址: https://gitcode.com/cann/cann-samples创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考