当前位置: 首页 > news >正文

cann/asc-devkit SinCosCompute性能调优样例

SinCosCompute性能调优样例

【免费下载链接】asc-devkit本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C++标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。项目地址: https://gitcode.com/cann/asc-devkit

概述

本样例以sincos计算为例,介绍Ascend C SIMT编程方式下的线程配置优化思路。样例包含1个基线版本以及1个优化版本,基线版本中未设置__launch_bounds__,编译器按照默认值1024(即每个Block内1024个线程)进行资源分配导致寄存器溢出,优化版本通过配置__launch_bounds__(512),提示编译器每个Block的最大线程数量为512,编译器根据提示在编译过程中充分利用硬件资源,从而避免寄存器溢出,展示SIMT编程方式下合理配置线程数优化性能的调优路径。

支持的产品

  • Ascend 950PR/Ascend 950DT

支持的CANN软件版本

  • >= CANN 9.1.0

目录结构介绍

sincos_compute/ │ ├── CMakeLists.txt // cmake编译文件 │ ├── sincos_compute.asc // sincos样例实现 │ └── README.md

样例描述

  • 样例功能

    使用sincosf函数同时计算sin和cos结果

    sincosf(input[idx], output_sin + idx, output_cos + idx)
  • 样例规格:

    样例类型(OpType)SinCosCompute
    样例输入nameshapedata typeformat
    input[393216]floatND
    样例输出output_sin[393216]floatND
    output_cos[393216]floatND
    核函数名sincos_thread_1024 / sincos_thread_512

样例实现

sincos计算说明

本样例使用Ascend C提供的sincosf接口同时计算sin/cos结果,样例中设置了固定shape,每个线程计算16个输入值,计算流程如下:

  1. 根据算子数据shape的切分逻辑,计算每个核的起始地址
  2. 调用Ascend C提供的sincosf接口,同时计算sin/cos结果

线程数与寄存器关系

在SIMT编程模型中,核函数定义时配置的最大线程数直接影响每个线程可用的寄存器数量:

最大线程数每个线程可用寄存器个数
1025~204816
513~102432
257~51264
1~256127

关键原则

  • 配置的最大线程数越大,每个线程可用寄存器数越少
  • 计算密集型算子,单个线程所需的寄存器通常较多,一般建议配置512或1024线程
  • 数据搬运类算子,单个线程所需的寄存器通常较少,一般建议配置2048线程
  • 当寄存器不足以存下所有的临时变量时,会出现寄存器溢出(register spill),数据会溢出到栈空间(Global Memory),导致性能下降

样例实现说明

本样例通过2个独立的kernel来体现__launch_bounds__的效果,每个kernel对应特定的Case版本。

Case实现特点使用的核函数优化特性
Case 0不设置launch bounds,使用默认值sincos_thread_1024基线版本,未配置__launch_bounds__
Case 1根据实际算子的计算规模,配置__launch_bounds__(512)sincos_thread_512编译器使用用户指定的配置值进行相应优化

性能指标说明

指标说明
Task Duration(us)整个任务执行的总时间,算子执行时间以该参数为准
DCache Read GMDCache从Global Memory读取数据的次数
DCache Read VectorVector Core从DCache读取数据的次数
DCache Write VectorVector Core向DCache写入数据的次数

Case 0: 基线版本(寄存器溢出)

样例目标:不配置__launch_bounds__,观察寄存器溢出对性能的影响

核心实现

  • 默认线程数为1024,每个Thread仅可用32个寄存器
  • sincosf计算需要更多寄存器,超出32个寄存器限制

关键代码

__global__ void sincos_thread_1024(float* input, float* output_sin, float* output_cos, uint64_t total_length) { int32_t blk_start_idx = blockIdx.x * THREADS_PER_BLOCK * PER_THREAD_LOOP; // 每个核计算 PER_THREAD_LOOP * THREADS_PER_BLOCK 的运算量 for (int i = 0; i < PER_THREAD_LOOP; i++) { int idx = blk_start_idx + i * THREADS_PER_BLOCK + threadIdx.x; sincosf(input[idx], output_sin + idx, output_cos + idx); } }

编译信息

使用--cce-res-usage编译选项查看寄存器使用情况:

[BISHENG] Function properties for _Z18sincos_thread_1024PfS_S_m_simt_entry: Stack size: 32 bytes, Used register number: 32

分析

  • Stack size: 32 bytes → 存在寄存器溢出
  • Used register number: 32 → 达到1024线程下的寄存器上限
  • 寄存器溢出导致中间数据存储到Global Memory,增加访存开销

性能数据

Task Duration(us)DCache Read GMDCache Read VectorDCache Write Vector
102.47256640768

性能瓶颈

  • 寄存器溢出到Global Memory
  • 额外的栈空间访问增加延迟
  • DCache Read Vector / DCache Write Vector次数较高(640次 / 768次)

优化方向:通过__launch_bounds__提示编译器真实的blockDim,充分利用寄存器资源,避免寄存器溢出。


Case 1: 优化版本(避免寄存器溢出)

优化目标:通过配置__launch_bounds__(512)避免寄存器溢出,充分利用寄存器资源,提升性能

核心优化

  • 指定__launch_bounds__(512),每个Thread可用64个寄存器
  • sincosf计算所需的寄存器在限制范围内

关键代码

__global__ __launch_bounds__(512) void sincos_thread_512(float* input, float* output_sin, float* output_cos, uint64_t total_length) { int32_t blk_start_idx = blockIdx.x * THREADS_PER_BLOCK * PER_THREAD_LOOP; // 每个核计算 PER_THREAD_LOOP * THREADS_PER_BLOCK 的运算量 for (int i = 0; i < PER_THREAD_LOOP; i++) { int idx = blk_start_idx + i * THREADS_PER_BLOCK + threadIdx.x; sincosf(input[idx], output_sin + idx, output_cos + idx); } }

编译信息

[BISHENG] Function properties for _Z17sincos_thread_512PfS_S_m_simt_entry: Stack size: 0 bytes, Used register number: 48

分析

  • Stack size: 0 bytes → 无寄存器溢出
  • Used register number: 48 → 在64个寄存器限制内
  • 所有中间数据保存在寄存器,避免Global Memory访问

性能数据

Task Duration(us)DCache Read GM(次)DCache Read Vector(次)DCache Write Vector(次)
96.22256512256

优化效果分析

  • Task Duration从102.47us降低到96.22us,耗时下降约6.1%
  • DCache Read GM保持不变,说明并没有增加额外开销
  • DCache Read Vector从640减小至512, DCache Write Vector从768减小至256,说明没有寄存器溢出后,对于Data Cache的读写次数减少(stack物理位置位于Global Memory,因此寄存器溢出时对于stack的访问会体现在Data Cache的访问次数上)
  • 寄存器充分利用,避免数据溢出到Global Memory

性能对比总结

Ascend 950PR性能数据

综合优化效果

  • 从Case 0基线版本到Case 1优化版本,Task Duration从102.47us降低到96.22us,耗时下降约6.1%
  • DCache Read Vector从640减小至512,DCache Write Vector从768减小至256
Case versionTask Duration(us)Task Duration相对Case 0优化点
Case 0102.471x基线版本,寄存器溢出到Global Memory
Case 196.220.94x耗时配置launch bounds避免寄存器溢出

调优建议

  1. 识别寄存器溢出:使用--cce-res-usage编译选项查看寄存器使用情况

    • Stack size > 0:存在寄存器溢出
    • Stack size = 0:无寄存器溢出
  2. 合理配置线程数

    • 计算密集型算子:建议512或1024线程
    • 数据搬运类算子:建议2048线程
    • 根据寄存器需求表选择合适的线程数配置
  3. 使用__launch_bounds__提示编译器

    __global__ __launch_bounds__(线程数) void kernel_name(...)
  4. 验证优化效果

    • 对比优化前后的编译信息(Stack size和Used register number)
    • 对比优化前后的性能数据(Task Duration、DCache Read GM、DCache Read Vector、DCache Write Vector)

编译运行

在本样例根目录下执行如下步骤,编译并执行样例。

  • 配置环境变量
    请根据当前环境上CANN开发套件包的安装方式,配置环境变量。

    source ${install_path}/cann/set_env.sh

    说明:${install_path}为CANN包安装目录,未指定安装目录时默认安装至/usr/local/Ascend下。

  • 样例执行

    mkdir -p build && cd build; # 创建并进入build目录 cmake -DCMAKE_ASC_ARCHITECTURES=dav-3510 ..;make -j; # 编译工程 ./sincos_compute 1024 # 执行基线样例 ./sincos_compute 512 # 执行优化样例
  • 编译选项说明

    选项可选值说明
    CMAKE_ASC_ARCHITECTURESdav-3510NPU 架构:本样例仅支持 dav-3510(Ascend 950PR/Ascend 950DT)

    执行结果如下,说明精度对比成功。

    [Success] Case accuracy is verification passed.

性能分析

使用msprof工具获取详细性能数据:

msprof op ./sincos_compute 1024 # 分析基线case的性能 msprof op ./sincos_compute 512 # 分析优化case的性能

命令完成后,会在默认目录下生成以"OPPROF_{timestamp}_XXX"命名的文件夹,性能数据文件夹结构示例如下:

├──dump # 原始的性能数据,用户无需关注 ├──ArithmeticUtilization.csv # cube/vector指令cycle占比 ├──L2Cache.csv # L2 Cache命中率 ├──Memory.csv # UB,L1和主存储器读写带宽速率 ├──MemoryL0.csv # L0A,L0B,和L0C读写带宽速率 ├──MemoryUB.csv # Vector和Scalar到UB的读写带宽速率 ├──OpBasicInfo.csv # 算子基础信息 ├──PipeUtilization.csv # 采集计算单元和搬运单元耗时和占比 ├──ResourceConflictRatio.csv # UB上的 bank group、bank conflict和资源冲突率在所有指令中的占比 └──visualize_data.bin # MindStudio Insight呈现文件

查看具体的性能分析结果:

# 如查看算子基础信息 cat ./OPPROF_*/OpBasicInfo.csv # 如查看内存相关数据 cat ./OPPROF_*/Memory.csv

【免费下载链接】asc-devkit本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C++标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。项目地址: https://gitcode.com/cann/asc-devkit

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

http://www.jsqmd.com/news/987922/

相关文章:

  • RPCS3终极指南:如何通过开源模拟器在PC上完美运行PS3游戏
  • StateSmith开发指南:从源码解析到贡献代码,成为开源项目参与者
  • pinche_xcx扩展功能开发:如何添加拼车费用计算与支付功能
  • 国际EMBA含金量高吗?2026五大高含金量国际EMBA项目解析 - 品牌2026推荐
  • Obsidian效率工具:Claudian插件的批量操作技巧
  • 如何让Continue成为你的AI编程搭档:从入门到精通的完整指南
  • vue表格使用 vxe-table 展开行实现产品列表与明细列表
  • 2026年6月最新版包头第三方CMACNAS甲醛检测治理机构口碑名单:万清CMA检测中心等5家公司深度测评万清CMA检测中心TOP1推荐 - 一修哥咨询
  • CodeX Docs进阶开发:从用户到贡献者的成长之路
  • GolangBypassAV反沙箱技术:规避动态检测的关键策略
  • 2026澳洲本地留学移民机构排行 附选型避坑指南 - 互联网科技品牌测评
  • Strecs3D实战案例:悬臂梁模型的填充优化前后对比与效果分析
  • GraphQL-Go-Tools完全指南:构建高性能GraphQL API网关的终极解决方案
  • 澳洲本地高成功率留学移民机构权威排行 - 互联网科技品牌测评
  • statannotations API深度解析:Annotator类的完整使用指南与最佳实践
  • 3步解决老旧Mac蓝牙失效:OpenCore Legacy Patcher实用指南
  • 如何在5分钟内上手Timeflake?Python开发者必备的高效UUID生成工具
  • 儿童益智玩具市场持续增长!国内十大新款竹蜻蜓厂家综合实力盘点(附选型建议) - 企师傅推荐官
  • MuJoCo肌腱系统深度解析:从生物力学建模到工程实践
  • 人生第一双高跟鞋品牌排行 轻奢舒适兼具纪念意义 - 起跑123
  • 2026年6月最新版定西第三方CMACNAS甲醛检测治理机构口碑名单:万清CMA检测中心等5家公司深度测评万清CMA检测中心TOP1推荐 - 一修哥咨询
  • OhMyREPL.jl与FZF集成:高效搜索REPL历史的完整教程
  • GoFish性能优化终极指南:10个加速软件包下载与安装的实用技巧
  • 2026年6月最新版东莞第三方CMACNAS甲醛检测治理机构口碑名单:万清CMA检测中心等5家公司深度测评万清CMA检测中心TOP1推荐 - 一修哥咨询
  • Point Cloud Utils终极指南:5个专业技巧实现高效3D点云处理
  • 2026年郑州航空港区搬家公司权威分析:专业服务深度解析与选择指南 - 品研笔录
  • DuckDB-rs Parquet文件支持:大规模数据分析的完整解决方案
  • 2026年6月最新版丹东第三方CMACNAS甲醛检测治理机构口碑名单:万清CMA检测中心等5家公司深度测评万清CMA检测中心TOP1推荐 - 一修哥咨询
  • 戴森球计划蓝图库:3000+工厂设计让你的星际帝国建设效率翻倍
  • 探索scodec核心组件:BitVector与Codec trait深度剖析 [特殊字符]