避免bank冲突NPU架构版本2201【免费下载链接】asc-devkit本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言原生支持C和C标准规范主要由类库和语言扩展层构成提供多层级API满足多维场景算子开发诉求。项目地址: https://gitcode.com/cann/asc-devkit【优先级】高[!NOTE]说明 该性能优化建议适用于如下产品型号Atlas A3 训练系列产品/Atlas A3 推理系列产品Atlas A2 训练系列产品/Atlas A2 推理系列产品【描述】为了提高数据访问的效率和吞吐量Unified Buffer采用了bank大小相等的内存模块结构设计。Unified Buffer总大小为192K划分为48个bank。每个bank由128行组成每行长度为32B。这48个bank进一步组织为16个bank group每个bank group包含3个bank例如bank15、bank31和bank47组成一个bank group。图1bank结构示意图图中箭头方向表示内存排布的顺序每个bank可以独立地进行数据的读写操作允许多个数据请求同时进行。然而当多个读写操作试图同时访问同一个bank或bank group时由于硬件资源的限制这些操作必须排队等待会导致bank冲突引起性能下降。具体来说Vector计算单元每拍一个指令周期能够从每个bank group中读取或写入一行数据。如果同一个API中的多个操作试图同时访问同一个bank或bank groupVector计算单元无法在同一个周期内处理所有请求导致这些请求排队等待。这种排队增加了数据访问的延迟降低了系统的整体性能。bank冲突的典型场景bank冲突主要可以分为以下三种场景读写冲突读操作和写操作同时尝试访问同一个bank。写写冲突多个写操作同时尝试访问同一个bank group。读读冲突多个读操作同时尝试访问同一个bank group。下文给出了一些具体的示例假设0x10000地址在bank16上0x10020在bank17上0x20020在bank33上如下图所示图2地址分配示意图读写冲突示例Vector指令的源操作数src和目的操作数dst同时读写到同一个bank时造成读写冲突具体分析如下表1读写冲突示例序号src地址dst地址bankbank group结论示例10x100200x10000bank_id0 ! bank_id1bank_group_id0 ! bank_group_id1src地址和dst地址分别属于bank16和bank17故无冲突。示例20x100200x10E20bank_id0 bank_id1bank_group_id0 bank_group_id1src地址和dst地址的地址都在bank17故存在冲突。写写冲突示例Vector指令目的操作数dst对应的8个DataBlockblock0-block7同时写到一个bank group时造成写写冲突具体分析如下表2写写冲突示例序号dst地址blk_strideblock0_addrblock1_addrblock2_addr...结论示例10x1FE00160x1FE000x200000x20200...8个DataBlock均在一个bank group下故全部冲突8拍完成一个Repeat的写入。示例20x1FE0080x1FE000x1FF000x20000...block0和block2在一个bank group存在冲突4拍完成一个Repeat的写入。读读冲突Vector指令多个源操作数同时读到同一个bank group时造成读读冲突具体分析如下表3双src场景读读冲突示例序号src0地址src1地址bankbank group结论示例10x100200x20020bank_id0 ! bank_id1bank_group_id0 bank_group_id1存在冲突。示例20x100200x10000bank_id0 ! bank_id1bank_group_id0 ! bank_group_id1无冲突。Vector指令某一个源操作数对应的8个DataBlockblock0-block7读到同一个bank group时造成读读冲突具体分析如下表4单src场景读读冲突示例序号src地址blk_strideblock0_addrblock1_addrblock2_addr...结论示例10x1FE00160x1FE000x200000x20200...8个DataBlock均在一个bank group下故全部冲突8拍完成一个Repeat的读操作。示例20x1FE0080x1FE000x1FF000x20000...block0和block2在同一个bank group下存在冲突4拍完成一个Repeat。[!NOTE]说明 通过msOpProf工具可以进行资源冲突占比的相关性能数据采集。 工具的具体使用方法和资源冲突占比文件性能数据文件说明请参考《msOpProf用户指南》。如何避免bank冲突避免bank冲突的方法有两种优化计算逻辑和优化地址分配。优化计算逻辑对一个shape为(8, 16, 16)的输入做(1, 0, 2)的transpose操作输出shape为(16, 8, 16)。通过将计算逻辑由“跳读连续写”修改为“连续读跳写”可避免冲突问题。实现方案对比如下实现方案原始实现优化实现实现方法跳读连续写同一Repeat内输入的8个DataBlock都在同一个bank group而发生读读冲突。连续读跳写同一个Repeat内输入的8个DataBlock不在同一个bank group内避免了读读冲突。示意图示例代码uint64_t mask 128; UnaryRepeatParams params; params.dstBlkStride 1; params.srcBlkStride 16; for(uint32_t i0; i16; i) { AscendC::Adds(dstLocal[i * 128], srcLocal[i * 16], 0, mask, 1, params); }uint64_t mask 128; UnaryRepeatParams params; params.dstBlkStride 8; params.srcBlkStride 1; for(uint32_t i0; i8; i) { AscendC::Adds(dstLocal[i * 16], srcLocal[i * 256], 0, mask, 2, params); }优化地址分配实现8192 × 8192half ND矩阵到全局紧凑NZ布局的转换切分后每个Tile块完成144 × 128half数据的转换。通过在内存分配时适当扩大内存调整单次搬运内相邻Datablock的地址步长保证在同一个Copy搬运操作内不同Datablock的写操作不会同时出现在一个bank group内。完整样例可参考避免bank冲突样例。 实现方案对比如下实现方案原始实现优化实现实现方法不做地址优化及搬运步长Copy时步长为144各个Tensor的地址分别为ND矩阵起始地址0x0tensor长度为144 * 128 * sizeof(half)字节NZ矩阵起始地址0x12000tensor长度为144 * 128 * sizeof(half)字节在每个Copy搬运操作内8个Datablock同时写一个bank group单条Copy从一拍拉长为8拍。优化地址及搬运步长为NZ矩阵多申请256字节即多申请一行UB内存空间Copy时步长为145各个Tensor的地址分别为ND矩阵起始地址0x0tensor长度为144 * 128 * sizeof(half)字节NZ矩阵起始地址0x12000tensor长度为145 * 128 * sizeof(half)字节NZ矩阵多申请256字节且将Copy时步长增大1避免Copy搬运时8个Datablock同时写一个bank group单条Copy在一拍内完成。示意图示例代码AscendC::LocalTensor nd(AscendC::TPosition::VECIN, 0, 144 * 128); AscendC::LocalTensor nz(AscendC::TPosition::VECOUT, 2 * 144 * 128 * sizeof(half), 144 * 128); AscendC::CopyRepeatParams copyParams; copyParams.dstStride 144; copyParams.srcStride 1; copyParams.dstRepeatSize 1; copyParams.srcRepeatSize 128 / 16;AscendC::Copy(nz[0], nd[0], static_castuint64_t(128), static_castuint8_t(144), copyParams);AscendC::LocalTensor nd(AscendC::TPosition::VECIN, 0, 144 * 128); AscendC::LocalTensor nz(AscendC::TPosition::VECOUT, 2 * 144 * 128 * sizeof(half), 145 * 128); // 多申请256字节 AscendC::CopyRepeatParams copyParams; copyParams.dstStride 145; // 搬运时地址步长增加1 copyParams.srcStride 1; copyParams.dstRepeatSize 1; copyParams.srcRepeatSize 128 / 16;AscendC::Copy(nz[0], nd[0], static_castuint64_t(128), static_castuint8_t(144), copyParams);更多的UB Bank冲突场景分析可参考bank冲突分析样例。【免费下载链接】asc-devkit本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言原生支持C和C标准规范主要由类库和语言扩展层构成提供多层级API满足多维场景算子开发诉求。项目地址: https://gitcode.com/cann/asc-devkit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考