昇腾学院 | Atlas性能调优之瓶颈分析
Atlas人工智能计算平台,提供端、边、云的全场景AI解决方案,以强大的算力助力客户开启AI未来并加速企业智能化进程。为更好的发挥硬件算力,负载更多的业务流量,从今天开始将陆续推出性能分析、优化相关文章,助力用户在Atlas平台上进行软件开发、调优。
本文主要阐述在性能出现瓶颈,业务无法增加时,通过哪些工具和方法,统计和观测性能数据,确定瓶颈点,从而方便进一步进行优化。
性能检查方法
npu-smi
2. 使用npu-smi info watch 命令可循环打印芯片的温度、AI Core占用率、AI Cpu占用率、Ctrl Cpu占用率、内存使用率、内存带宽占用率等信息。
使用npu-smi info watch -h
可以查看该命令的详细参数,常用参数如下
-i 指定卡号
-c 指定芯片
-d 输出间隔时间
日志
日志是分析定位问题的最好手段,在matrix框架中,用户需要定义自己的日志级别,这样框架会将日志收集存放到/var/dlog
中
在Host侧和Device侧的公共头文件中如下定义即可
#define USE_DEFINE_ERROR 0x6001 enum { HIAI_IDE_ERROR_CODE, HIAI_IDE_INFO_CODE, HIAI_IDE_WARNING_CODE }; HIAI_DEF_ERROR_CODE(USE_DEFINE_ERROR, HIAI_ERROR, HIAI_IDE_ERROR, ""); HIAI_DEF_ERROR_CODE(USE_DEFINE_ERROR, HIAI_INFO, HIAI_IDE_INFO, ""); HIAI_DEF_ERROR_CODE(USE_DEFINE_ERROR, HIAI_WARNING, HIAI_IDE_WARNING, "");
注意:系统的默认日志级别为ERROR,不建议修改日志级别,会占用大量的带宽资源和Ctrl Cpu资源,建议直接打ERROR级别的日志。
Engine队列长度
Matrix框架中的每一个Engine都有一个队列用于缓存数据,默认大小为200,上一个engine调用SendData接口后,数据会发送到该队列中,然后HIAI_IMPL_ENGINE_PROCESS
函数会从中取数据进行运算,当计算速度比SendData慢时,该队列会出现堆积的情况
在每个Engine的HIAI_IMPL_ENGINE_PROCESS
函数中,添加以下内容,便可以打印该Engine对应接收端口的队列长度
int portId = 0; HIAI_ENGINE_LOG(HIAI_IDE_ERROR, "VdecEngine Queue Size:%d", GetQueueCurrentSize(portId));
Engine整体耗时
统计Engine的耗时,有助于我们分析,从而对Engine进行拆分、合并,修改Engine的配置参数,以达到最优性能。
关键耗时统计
一般来说,在整个流程中,比较耗时的地方有三点,硬件编解码、模型推理、推理数据的前后处理
编解码耗时
硬件编解码这块性能固定,具体性能参数请参考《DVPP API参考》,在没有异常帧、不支持的数据输入的情况下,性能比较稳定,不会成为瓶颈。如果发现视频、图片解码失败或耗时过长,可查看dlog中的device日志。
模型推理耗时
模型推理一般是最耗时的任务,主要使用AIModelManger->Process
函数,调用该接口,会完成对输入数据的模型推理工作,该功能主要使用了昇腾310芯片中的AI Core和AI Cpu
统计该函数的耗时,方便我们对模型的评估
推理的前后处理耗时
整个推理流程,另外一个比较耗时的地方就是推理数据的前后处理,涉及到数据的计算、内存拷贝等,主要使用昇腾310芯片的Ctrl CPU。
耗时统计方法
统计关键操作的耗时,可以使用以下方法获取当前时间
struct timeval curTime;gettimeofday(&curTime, NULL);
统计关键函数的调用时间差,并使用HIAI_ENGINE_LOG
打印耗时
注意:Host侧和Device侧时间不完全同步,跨侧统计时间没有意义
瓶颈定位和一般优化方法
运行
在代码中加入以上的Engine队列统计、Engine耗时和关键点耗时统计,使用命令rm -rf /var/dlog/*
清空本地日志,再运行程序直至出现性能问题后关闭。
分析
对程序加压,一般会出现反压的情况,即整个流程处理时间越来越慢,向graph中SendData出现超时等情况
查看日志,找出最先出现队列堆积的Engine,说明该Engine为性能瓶颈。
如果是解码Engine,查看《DVPP API参考》,确定有没有超出性能指标,如果没有超过,检查是否使用了多线程,像Jpegd、Vdec等硬件解码模块,多线程下才能达到最佳性能,同时检查dlog中的device日志,看看有没有解码的错误,对于错误的输入数据,DVPP硬解码失败后,会尝试调用软件解码,这耗时比较长,所以想保证解码的速率的话,需要优先保证输入数据的正确性。
如果是推理Engine,查看预处理、推理耗时和后处理的耗时情况
预处理一般建议模型转换的时候设置AIPP为yuv转为原模型要求的输入,注意,这一步是直接使用AI Core进行色域转换,比软件转效率更好,这样就可以将解码完的yuv数据直接送入模型推理。
如果推理的耗时过长,有下面几个优化点
修改graph描述文件,提高该模型所在Engine的
thread_priority
测试该模型多batch下耗时,如果多batch性能更佳,可考虑修改代码,使用多batch
使用profiling工具分析模型里面算子耗时,看看有没有优化空间
如果后处理耗时过长,先将后处理单独拆分出一个Engine,有多种优化方法
将Engine设置成多线程,Device侧有4个Ctrl Cpu,使用多线程可提高并发
将Engine移动到Host侧,使用Host性能更好的Cpu来计算
使用openmp优化for循环,通过并行来提高for循环的执行速度
使用Neno,Ctrl Cpu为Arm aarch64架构,可使用neno来对代码提速
另外,如果Host侧接收Engine最先出现堆积,可重点分析是否是回调函数或者接收处理耗时过长导致反压的。
本文只是简单介绍了Matrix开发框架的瓶颈分析方法,接下来,将会从流程编排、编解码、内存管理和模型调优方面进一步介绍。
- 点赞
- 收藏
- 关注作者
评论(0)