指令数问题分析,如何抓取指令数进行问题拆解和分析。

以华为视频本地视频滑动场景指令数超标为案例,详细描述如何抓取指令数进行问题拆解和分析。

HarmonyOS
2024-06-13 11:04:16
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
netos

通过命令直接获取指令数

(1)先通过命令获取应用的进程id

hdc shell 
ps -ef | grep himovie

(2)直接用命令获取,以下命令代表抓取10s内的指令数,执行命令后可在期间进行操作。其中hw-instructions代表指令数

单框架:

hdc_std shell "hiperf stat -e hw-cpu-cycles,hw-instructions -p $(pidof com.huawei.hmsapp.himovie) -d 10"

该问题场景,可以在执行命令过程中执行滑动页面的自动化指令,根据测试用例,可以执行两次,最终获取对应的指令数。

hdc shell uinput -T -m 500 1800 500 1200 1000

adb shell "simpleperf stat -e instructions,cpu-cycles -p `pidof com.huawei.himovie` --duration 10

抓取所有线程指令数辅助分析

想获取所有线程的指令数进行拆解,辅助定位某场景的指令数超标或者CPU负载问题,有两种方式,一种是通过simplePerf,另一种是Hiperf。因为双框架是用simplePerf抓取的,所以用simplePerf对比更准确一点,但是simplePerf抓取火焰图比较麻烦。HiPerf可以直接抓取出饼图和火焰图,以下两种方式可供选择。

使用Hiperf

(1)通过命令在执行具体操作时抓取指令数信息。生成perf.data文件并存储在/data/perf.data目录下。

hiperf record -e hw-instructions -s dwarf -p $(pidof xxx) -d 10 -o /data/perf.data

(2)导出perf.data文件

hdc file recv /data/perf.data

(3)解压附件中hiperf.rar,并将perf.data的文件放到解压的hiperf文件夹中

(4)拷贝设备对应的ROM镜像对应的lib.unstripped、exe.unstripped,放到hiperf文件目录下。lib.unstripped、exe.unstripped这两个文件从下载镜像的网页下载。(路径为BiddingDoc\base_package\config\ system_component_config)

拷贝至hiperf文件夹:

(5)执行命令python recv_binary_cache.py -l E:\tools\hiperf\exe.unstripped E:\tools\hiperf\lib.unstripped会在hiper目录下生成binary_cache目录,生成后检查一下目录是否为空

(6)从lib.unstripped文件夹中拷贝libc.so放到上一步生成的binary_cache\system\lib目录下,并修改名字为ld-musl-aarch64.so.1

(7)执行python make_report.py -l F:\tools\hiperf\binary_cache,生成hiperf_report.html。双击打开对应html,即可看到进程总指令数和各线程指令数

点击Flam Graph可以展示火焰图,有具体的代码堆栈

使用SimplePerf

获取指令数饼图

(1)需要先安装simplePerf,把simpleperf导入到目录/system/bin并修改权限。

hdc file send E:\tools\simpleperf /system/bin 
hdc shell 
chmod 777 simpleperf

(2)同样的通过命令抓取操作过程中的指令数据

simpleperf record -e instructions -p $(pidof xxx) --duration 10 -o /data/ros.data

(3)把设备中的ros.data文件从设备中导出来,下载并解压附件中的getInstructions.rar,将导出来的文件放到perf目录

hdc file recv /data/ros.data

(4)可以通过toHTML.bat文件修改data文件和生成后的report文件目录

(5)执行脚本toHTML.bat,会在report目录下生成一个html文件,打开即可看到进程总指令数和各线程的指令数。但是没有生成火焰图。

符号表解析对应指令

以上的步骤能够获取各子线程对应的指令数和占比,但是没有对应的火焰图和堆栈。我们可以找到其中占比比较大的so,饼图上会展示方法对应的偏移量,可以通过符号表解码获取对应执行的方法。

(1)到ROM镜像下载的地址找到对应的so,都是在目录BiddingDoc\base_package\config\system_component_config\lib.unstripped下。该场景下libace_campatible.z.so占比将近一半,该so在lib.unstripped\arkui\ace_engine下下载。跟arkui相关的基本都在arkui这个目录下。

(2)使用addr2line工具,执行命令根据方法的偏移量找到对应的方法。

addr2line -fCpie libace_campatible.z.so 4f6d2c

但是这样只能看几个占比比较高的方法,看不了全局和详细的堆栈,仍然不太好定位。但是该方法同样可以适用于使用profile看堆栈的时候解析偏移量获取底层的对应的方法。

问题解析

1. 查看生成的指令数数据

根据以上的方法可以获取视频滑动场景详细的各线程的指令数,通过饼图我们可以发现,该场景主要是由于libace_campatible.z.so执行的指令数在主线程中占了43.7%。这个场景其实主要就是通过arkui进行布局和渲染,所以符合场景。

而在该so中占比较高的是DecStrongRef()方法,与上面我们用符号表解析是一致的,但这个方法应用侧看不出来这是在执行什么,需要向arkui开发求助。

查看对应的火焰图,通过火焰图一目了然,主要都是在执行FlushVsync,其中HandleOnAreaChangeEvent和HandleVisibleAreaChangeEvent横向占比比较高,说明在执行的时间和指令数占比比较高。

从trace上看滑动时每一帧的Vsync在5ms+,其中确实OnAreaChange的耗时占比也是比较高的。

2. 分析代码

查看该场景的代码发现并未使用这两个方法,找ArkUI的同事增加trace点,查看是什么组件绑定了OnAreaChange事件。日志打印发现都是ListItem和searchField组件,都不是该场景页面里的。

而这些组件都是首页里的,因为这两个页面都是通过Navigation跳转,首页会下渲染树,但是不会下组件树。了解ArkUI的机制,发现当前代码逻辑,每次的FlushVsync都会把所有组件树上节点绑定的OnAreaChange都遍历一遍,并且不论是否使用了OnVisibleChange事件都会触发执行计算。这显然是不合理的

3. 验证影响

让ArkUI把这两个方法的代码屏蔽掉,保证先不触发这两个方法后复测视频滑动的场景。测试结果如下,从trace上可以看到每帧FlushVsync的时间缩短至1ms+,而指令数也减少了将近一半,可以达标,所以得出结论,该场景问题关键点在于这两个方法的冗余计算。该问题已提单给ArkUI对这两个接口进行剪枝。

问题总结

1. 指令数的拆解两种工具都可以使用,总体而言建议使用Hiperf抓取更为简单,信息更全面。

2. OnAreaChange这个方法当前DFX能力不足,应用侧无法直接通过日志或debug开关来获取其绑定的组件信息,需要依赖ArkUI的开发增加日志信息,该点已提意见。

3. OnAreaChange方法当前问题比较多,性能较差,使用需谨慎,除非当前无替代方案,另外ArkUI计划会有需求,将该接口拆分为大小和位置两个回调,使用场景进行区分避免冗余的回调。

分享
微博
QQ
微信
回复
2024-06-13 21:55:27
相关问题
HarmonyOS 要如何分析性能问题
73浏览 • 1回复 待解决
HarmonyOS参与者的问题分析
7742浏览 • 4回复 待解决
响应时延/掉帧性能问题分析
951浏览 • 1回复 待解决
关于启动慢问题首帧卡顿分析
392浏览 • 1回复 待解决
冷启动首帧完成时延问题分析
397浏览 • 1回复 待解决
PolarDB可以支持多少并发?
2655浏览 • 1回复 待解决
HarmonyOS 设备获取每日步
312浏览 • 1回复 待解决
如何在HarmonyOS中使用neon指令
428浏览 • 1回复 待解决
如何在线上进行应用状态的数据分析
397浏览 • 1回复 待解决