cann/asc-devkit:避免bank冲突(NPU架构版本2201)
避免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结构示意图(图中箭头方向表示内存排布的顺序)
.png "bank结构示意图(图中箭头方向表示内存排布的顺序)"?utm_source=gitcode_repo_files)
每个bank可以独立地进行数据的读写操作,允许多个数据请求同时进行。然而,当多个读写操作试图同时访问同一个bank或bank group时,由于硬件资源的限制,这些操作必须排队等待,会导致bank冲突,引起性能下降。
具体来说,Vector计算单元每拍(一个指令周期)能够从每个bank group中读取或写入一行数据。如果同一个API中的多个操作试图同时访问同一个bank或bank group,Vector计算单元无法在同一个周期内处理所有请求,导致这些请求排队等待。这种排队增加了数据访问的延迟,降低了系统的整体性能。
bank冲突的典型场景
bank冲突主要可以分为以下三种场景:
- 读写冲突:读操作和写操作同时尝试访问同一个bank。
- 写写冲突:多个写操作同时尝试访问同一个bank group。
- 读读冲突:多个读操作同时尝试访问同一个bank group。
下文给出了一些具体的示例,假设,0x10000地址在bank16上,0x10020在bank17上,0x20020在bank33上,如下图所示:
图2地址分配示意图

读写冲突示例
Vector指令的源操作数src和目的操作数dst同时读写到同一个bank时造成读写冲突,具体分析如下:
表1读写冲突示例
写写冲突示例
Vector指令目的操作数dst对应的8个DataBlock(block0-block7)同时写到一个bank group时造成写写冲突,具体分析如下:
表2写写冲突示例
读读冲突
Vector指令多个源操作数同时读到同一个bank group时造成读读冲突,具体分析如下:
表3双src场景读读冲突示例
Vector指令某一个源操作数对应的8个DataBlock(block0-block7)读到同一个bank group时造成读读冲突,具体分析如下:
表4单src场景读读冲突示例
[!NOTE]说明 通过msOpProf工具可以进行资源冲突占比的相关性能数据采集。 工具的具体使用方法和资源冲突占比文件性能数据文件说明请参考《msOpProf用户指南》。
如何避免bank冲突
避免bank冲突的方法有两种:优化计算逻辑和优化地址分配。
优化计算逻辑
对一个shape为(8, 16, 16)的输入做(1, 0, 2)的transpose操作,输出shape为(16, 8, 16)。通过将计算逻辑由“跳读,连续写”修改为“连续读,跳写”可避免冲突问题。实现方案对比如下:
优化地址分配
实现
8192 × 8192half ND矩阵到全局紧凑NZ布局的转换,切分后,每个Tile块完成144 × 128half数据的转换。通过在内存分配时适当扩大内存,调整单次搬运内相邻Datablock的地址步长,保证在同一个Copy搬运操作内,不同Datablock的写操作不会同时出现在一个bank group内。完整样例可参考避免bank冲突样例。 实现方案对比如下:
更多的UB Bank冲突场景分析可参考bank冲突分析样例。
【免费下载链接】asc-devkit本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C++标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。项目地址: https://gitcode.com/cann/asc-devkit
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
