昇腾学院 | Atlas性能调优之瓶颈分析

举报
xiongoal 发表于 2020/03/25 01:24:01 2020/03/25
【摘要】 Atlas人工智能计算平台,提供端、边、云的全场景AI解决方案,以强大的算力助力客户开启AI未来并加速企业智能化进程。为更好的发挥硬件算力,负载更多的业务流量,从今天开始将陆续推出性能分析、优化相关文章,助力用户在Atlas平台上进行软件开发、调优。本文主要阐述在性能出现瓶颈,业务无法增加时,通过哪些工具和方法,统计和观测性能数据,确定瓶颈点,从而方便进一步进行优化。 性能检查方法npu-...

Atlas人工智能计算平台,提供端、边、云的全场景AI解决方案,以强大的算力助力客户开启AI未来并加速企业智能化进程。为更好的发挥硬件算力,负载更多的业务流量,从今天开始将陆续推出性能分析、优化相关文章,助力用户在Atlas平台上进行软件开发、调优。

本文主要阐述在性能出现瓶颈,业务无法增加时,通过哪些工具和方法,统计和观测性能数据,确定瓶颈点,从而方便进一步进行优化。  


性能检查方法

npu-smi

  1. 使用npu-smi info查看芯片的硬件信息和当前驱动版本信息

spacer.gif   npu-smi_info.png

 2. 使用npu-smi info watch 命令可循环打印芯片的温度、AI Core占用率、AI Cpu占用率、Ctrl Cpu占用率、内存使用率、内存带宽占用率等信息。

spacer.gif    npu-smi_info_watch.PNG

      使用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开发框架的瓶颈分析方法,接下来,将会从流程编排、编解码、内存管理和模型调优方面进一步介绍。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。