芯片解决方案--SL8541e-系统性能优化总结
背景 伙伴反馈,设备操作卡顿,OH基础系统版本应用操作慢,应用人机交互体验差。 确定优化思路 常见优化思路 性能体验是一个很主观的评价,背后的因素很多,怎么通过技术手段找到背后的因素呢?先得转换成客观的评价。 从背后看影响因素和从正面看客观评价,是两种性能优化的方法。 性能问题的本质就是系统资源已经达到了瓶颈。“背后看影响因素”强调的是性能问题出现时的资源瓶颈。“正面看客观评价”强调的是性能问题出
背景
伙伴反馈,设备操作卡顿,OH基础系统版本应用操作慢,应用人机交互体验差。
确定优化思路
常见优化思路
性能体验是一个很主观的评价,背后的因素很多,怎么通过技术手段找到背后的因素呢?先得转换成客观的评价。
从背后看影响因素和从正面看客观评价,是两种性能优化的方法。
性能问题的本质就是系统资源已经达到了瓶颈。“背后看影响因素”强调的是性能问题出现时的资源瓶颈。“正面看客观评价”强调的是性能问题出现时的外部表象。
如果问题场景下,能够看到资源出现了明显瓶颈,比如内存不足,那就优先处理资源瓶颈。
背后的因素:
正面的客观评价:
确定本问题的优化思路
回到我们的问题,我们能直观的看到资源瓶颈吗,先做一番初步调查。
首先,看下8541e开发板的硬件能力,对硬件产品能力有个认识。
8541e的CPU、GPU、Memory都比rk3568差很多,低了不止一个档次,但这是问题的原因吗?
其次,针对应用操作反应慢的问题进行调查。
将应用操作反应慢,这个笼统的描述进一步细化,有3个问题:
1、点击应用后反应迟钝;
2、启动过程不流畅;
3、滑动不流畅
看下做这些操作前的基础资源使用情况:
CPU: 总CPU 400%,占用10%~24%波动,剩余375%以上,CPU充足;前台任务调度优先级高。
内存:1G内存机器占用剩余400M,内存充足;对比2G内存剩余更多,问题也存在
GPU:当前分支上没有合入GPU渲染,但以前在3.1release上合入过GPU渲染,也还是慢。
根据上述情况可以判断:这是常见基础资源充足的情况下的应用交互问题。
没法直观的看到资源差距,我们的思路就是:从正面评价看差距,在针对性分析和优化。
如何正面的客观评价? 我们需要有客观标准的性能指标和对应的测试方法,避免不同的人主观意识不一样,导致出现不同的评价结果。
确定性能指标KPI
怎么确定性能指标呢?
1、根据我们的优化目标,选择典型的应用交互场景,确定指标项。
2、摸底和对标测试,确定每个指标项的目标值。
分类 |
特性 |
指标名称 |
单位 |
达标值 |
挑战值 |
Android对标数据 |
测试数据(1127版本) |
应用 |
应用启动 |
空应用冷启动时长 |
ms |
950 |
800 |
1145 |
1068 |
应用 |
应用启动 |
首页带图应用冷启动时长 |
ms |
1100 |
950 |
1301 |
1584 |
应用 |
界面切换 |
纯文本界面切换时长 |
ms |
500 |
450 |
502 |
569 |
应用 |
界面切换 |
带图界面切换时长 |
ms |
650 |
550 |
669 |
935 |
应用 |
帧率 |
带图列表页面滑动帧率 |
fps |
56 |
60 |
56 |
12.1 |
整机 |
开机内存 |
开机后静置使用内存 |
M |
512 |
480 |
剩余内存:415M 使用内存:472M |
MemTotal:890M 剩余内存:480M 使用内存:410M |
根据对比测试的情况可以发现:
- 流畅度指标(帧率),差距大,是体验瓶颈,需重点优化。
- 速度指标(各种时长),有差距,需优化。
- 开机内存,已优于Android,可顺带优化。
帧率优化
帧率优化 1——初始版本分析
分析
帧率跟图形渲染、合成、VSYNC等有关;分离渲染场景下,应用进行渲染,render_service负责合成,都由VSYNC触发。
虽然当前版本采用CPU渲染和CPU合成,但是合入开源GPU渲染的版本,效果也不怎么样。需要分析下原因。
分析渲染和合成耗时,抓取systrace进行分析合成和渲染的情况。
首先是合成部分的trace。
从上述trace可以看到,
render_service进程:处理每帧需要100ms左右,最高120ms,耗时主要在H:Commit函数。
对比rk3568,H:Commit耗时只有6ms左右。
H:Commit对应HdiDevice::Commit,主要调用适配层HdiDisplay::Commit,负责图形合成和提交送显。进一步加trace确认是合成gfx耗时,长时间占用CPU。
然后是渲染部分的trace。
可以看到,
应用渲染线程:部分帧耗时高,90~120ms。子过程rsSurface->RequestFrame和H:ProcessRenderNodes都很耗时。
RequestFrame主要为等待耗时, H:ProcessRenderNodes为CPU耗时。
分析结论
合成和渲染太慢,导致帧率低;二者在流水线是先后两个步骤,但从整体帧率的影响看两者是“并行”关系,只优化处理其中一个,帧率提升程度都有限。
同时合成和渲染太慢,也增加了100ms以上的启动时延、界面切换时延。
优化措施
采用专项硬件进行渲染和合成。
渲染需要采用GPU渲染,8541e上目前没有闭源GPU,只能采用开源GPU,因此合入开源GPU;
合成需要采用硬件合成,8541e上有专项硬件模块GSP、DPU支持合成加速,但工作量较大,且需要原厂配合,时间较长;权宜之计,先采用GPU合成。
优化效果
- 流畅度明显提升,可日常使用,对比Android仍有差距。
- 帧率KPI大幅提升;
- 应用启动和界面切换这种速度KPI也有提升,超越了Android。
帧率优化2——分析
分析
上一步优化后,渲染平均耗时21.755ms,合成送显平均耗时15.183ms。渲染有少量等待,合成有大段等待。
继续查看binder通信对端,发现它也block在RequestBuffer上,等待另外的合成提交线程,当合成提交线程完成H:Commit释放Buffer之后,binder通信对端就可以申请到buffer,答复给渲染线程。
合成与提交在同一线程,更是如此。
也就是说,
1、渲染需要等待图形Commit释放Buffer之后,才能申请到新的图形Buffer;
2、合成需要等待图形Commit之后,才能进行下一帧的合成。
走读Commit提交的代码,跟踪到DRM驱动内核,发现在提交的处理中,当前是默认的block模式,会等待送显完成才会继续往下走。
分析结论
提交模式不正确,导致每帧出现几毫秒的buffer等待,影响帧率。
优化措施
设置提交为nonblock模式,异步提交送显,避免buffer分配等待。
优化效果
分类 |
特性 |
指标名称 |
单位 |
达标值 |
挑战值 |
Android对标数据 |
测试数据 |
测试数据 |
测试数据 |
应用 |
帧率 |
带图列表页面滑动帧率 |
fps |
56 |
60 |
56 |
12.1 |
39 |
49 |
渲染平均耗时16ms,合成送显平均耗时7.962ms,都没有了大段等待。
帧率优化3
分析
渲染已经降低到17ms,合成已经降低到7.9ms,但帧率仍然无法提升到50以上。为什么?
帧率跟3个因素有关,渲染、合成、VSYNC,既然渲染、合成满足要求了,那再看看vsync。
分析systrace发现,软件vysnc固定是20ms。
走读VSYNC的适配代码,软件发现VSYNC信号被其他开发者随手写死为20ms了。
分析结论
VSYNC适配不当,导致帧率无法超过50fps。
优化措施
驱动移植使能硬件VSYNC,软件VSYNC不再写死,与硬件VSYNC同步。
优化效果
分类 |
特性 |
指标名称 |
单位 |
达标值 |
挑战值 |
Android对标数据 |
测试数据 |
测试数据 |
测试数据 |
测试数据 |
应用 |
帧率 |
带图列表页面滑动帧率 |
fps |
56 |
60 |
56 |
12.1 |
39 |
49 |
55 |
帧率优化4
分析
经过上一轮优化,帧率已经解决Android系统的56帧了,还差一点点。主要瓶颈是渲染。当前8541E上开源GPU渲染耗时17.197ms,离60帧率的16.6ms,差0.5ms。
分阶段对比分析下渲染耗时情况。
OHOS版本 |
3.2-beta3 |
3.2-beta4 |
||||||
开发板 |
RK3568 |
8541E |
RK3568 |
|||||
渲染方案 |
闭源GPU |
开源GPU |
开源GPU |
开源GPU |
闭源GPU |
开源GPU |
||
合成方案 |
硬件加速 |
硬件加速 |
GPU |
GPU |
硬件加速 |
硬件加速 |
||
渲染耗时 OnVsync 单位:ms |
Render |
RequestFrame:请求Buff |
0.094 |
2.401 |
2.288 |
2.195 |
0.098 |
1.644 |
RenderNodes:节点转buff |
5.862 |
5.299 |
5.314 |
6.73 |
2.811 |
3.109 |
||
FlashFrame:buff送GPU |
3.523 |
4.147 |
4.166 |
4.411 |
5.267 |
4.128 |
||
其它合计 |
3.444 |
1.761 |
1.86 |
2.156 |
1.542 |
1.562 |
||
其它合计 |
1.812 |
1.793 |
1.886 |
1.705 |
1.576 |
1.569 |
||
总计 |
14.735 |
15.401 |
15.514 |
17.197 |
11.294 |
12.012 |
分析结论
通过对比可以得出如下结论:
1、开源GPU渲染比闭源GPU渲染耗时长,在RequestFrame的时候多了1.5到2ms。
开源GPU请求buffer的路径长,跨进程交互。闭源GPU的分配过程看不到,没有跨进程交互。
路径:应用->render_service client->skia egl->mesa->render_service->display hdi->libdrm->drm driver
2、OpenHarmony Beta4相比Beta3版本,RenderNodes耗时减少3ms。当前8541e采用的OpenHarmony版本是3.2Beta3。
3、由于当前渲染和合成都采用GPU,而8541e的GPU很差,两个功能存在抢占资源的情况。
优化措施
1、升级新版本
2、采用GSP + DPU硬件合成
优化效果
升级新版本,并采用GSP+DPU硬件合成加速,帧率提高到58.6帧。接近极限60帧,已高于A系统56帧。
合成trace,平均时延5ms:
渲染trace,平均时延16.7ms:
应用启动优化
初始版本分析
使用DevEco Testing进行应用启动性能测试
初始版本,卡顿次数多,受渲染合成速度影响较大。GPU渲染和合成,合入之后,应用启动和界面切换速度已优于Android。为了使体验更好,继续进一步分析优化。
分类 |
特性 |
指标名称 |
单位 |
达标值 |
挑战值 |
Android对标数据 |
测试数据 |
测试数据 |
应用 |
应用启动 |
空应用冷启动时长 |
ms |
950 |
800 |
1145 |
1068 |
1067 |
应用 |
应用启动 |
首页带图应用冷启动时长 |
ms |
1100 |
950 |
1301 |
1584 |
1200 |
应用 |
界面切换 |
纯文本界面切换时长 |
ms |
500 |
450 |
502 |
569 |
464 |
应用 |
界面切换 |
带图界面切换时长 |
ms |
650 |
550 |
669 |
935 |
434 |
空应用启动分析
从系统层面将应用启动划分阶段进行对比分析
序号 |
主阶段 |
子阶段 |
trace数据分解 |
备注 |
||||
rk3568耗时(ms) |
8541e耗时(ms) |
耗时偏差(ms) |
8541e-GPU耗时(ms) |
耗时偏差(ms) |
||||
1 |
应用点击 -> Launcher.OnTouchEvent |
|
|
|
|
|
|
|
2 |
Launcher.OnTouchEvent.Down到Launcher.OnTouchEvent.Up |
|
|
|
|
|
|
|
3 |
Launcher.OnTouchEvent.Up |
|
9.651 |
8.992 |
-0.659 |
8.34 |
-0.652 |
|
4 |
AbilityRuntime::ServiceExtensionContext::StartAbility |
|
31.145 |
14.873 |
-16.272 |
21.808 |
6.935 |
|
|
|
MainThread::Init |
2.312 |
1.326 |
-0.986 |
1.542 |
0.216 |
|
MainThread::Attach |
2.877 |
2.483 |
-0.394 |
2.774 |
0.291 |
|
||
MainThread::HandleLaunchApplication |
140.348 |
145.269 |
4.921 |
162.458 |
17.189 |
|
||
MainThread::HandleLaunchAbility |
59.61 |
104.236 |
44.626 |
104.161 |
-0.075 |
经分析trace发现:该函数在8541e上调用存在线程Uninterruptible Sleep的情况,与耗时偏差基本吻合,也就是等待IO或者系统调用比较慢。 |
||
AbilityThread::HandleAbilityTransaction |
49.94 |
98.648 |
48.708 |
125.336 |
26.688 |
经分析trace发现: |
||
UIContentImpl::CommonInitialize |
101.358 |
211.204 |
109.846 |
127.648 |
-83.556 |
经分析trace发现: |
||
OnSurfaceChanged |
3.451 |
14.334 |
10.883 |
23.333 |
8.999 |
|
||
JsiDeclarativeEngine::LoadJs |
1.905 |
2.676 |
0.771 |
5.857 |
3.181 |
|
||
PushPage |
5.558 |
10.628 |
5.07 |
10.463 |
-0.165 |
|
||
6 |
RSRenderThread::OnVsync |
RSRenderThread DrawFrame |
35.456 |
106.829 |
71.373 |
28.631 |
-78.198 |
GPU渲染和合成合入之后已优化 |
7 |
total |
|
678 |
882 |
204 |
825 |
-57 |
|
8 |
DevEco Testing测试结果 |
|
618.2 |
912 |
293.8 |
890 |
-22 |
|
带图应用启动分析
序号 |
主阶段 |
子阶段 |
trace数据分解 |
备注 |
|||||||
rk3568 |
8541e |
8541e空应用较rk3568 |
8541e带图应用较rk3568 |
||||||||
空应用耗时(ms) |
带图应用耗时(ms) |
带图应用较空应用 |
空应用耗时(ms) |
带图应用耗时(ms) |
带图应用较空应用 |
||||||
1 |
应用点击 -> Launcher.OnTouchEvent |
|
|
|
|
|
|
|
|
|
|
2 |
Launcher.OnTouchEvent.Down到Launcher.OnTouchEvent.Up |
|
|
|
|
|
|
|
|
|
|
3 |
Launcher.OnTouchEvent.Up |
|
6.884 |
13.914 |
7.03 |
34.4 |
3.379 |
-31.021 |
27.516 |
-10.535 |
|
4 |
AbilityRuntime::ServiceExtensionContext::StartAbility |
|
28.882 |
24.51 |
-4.372 |
17.974 |
39.17 |
21.196 |
-10.908 |
14.66 |
|
|
|
MainThread::Init |
3.395 |
1.826 |
-1.569 |
1.384 |
1.831 |
0.447 |
-2.011 |
0.005 |
|
MainThread::Attach |
2.992 |
3.58 |
0.588 |
2.898 |
4.501 |
1.603 |
-0.094 |
0.921 |
|
||
MainThread::HandleLaunchApplication |
42.38 |
37.597 |
-4.783 |
152.209 |
148.735 |
-3.474 |
109.829 |
111.138 |
同空应用 |
||
MainThread::HandleLaunchAbility |
75.143 |
78.73 |
3.587 |
135.467 |
132.163 |
-3.304 |
60.324 |
53.433 |
|
||
AbilityThread::HandleAbilityTransaction |
45.258 |
65.949 |
20.691 |
90.498 |
97.895 |
7.397 |
45.24 |
31.946 |
|
||
UIContentImpl::CommonInitialize |
105.324 |
105.45 |
0.126 |
124.424 |
277.99 |
153.566 |
19.1 |
172.54 |
同空应用 |
||
OnSurfaceChanged |
3.888 |
4.175 |
0.287 |
30.355 |
14.72 |
-15.635 |
26.467 |
10.545 |
|
||
JsiDeclarativeEngine::LoadJs |
6.31 |
5.429 |
-0.881 |
3.621 |
6.243 |
2.622 |
-2.689 |
0.814 |
|
||
PushPage |
6.617 |
89.252 |
82.635 |
25.7 |
114.39 |
88.69 |
19.083 |
25.138 |
|
||
6 |
RSRenderThread::OnVsync |
RSRenderThread DrawFrame |
35.419 |
134.575 |
99.156 |
30.872 |
224.618 |
193.746 |
-4.547 |
90.043 |
渲染能力,在帧率优化中提升 |
7 |
total |
|
590 |
757 |
167 |
|
|
|
-590 |
-757 |
|
8 |
DevEco Testing测试结果 |
|
543.8 |
602.2 |
58.4 |
|
|
|
|
|
|
进一步分解分析
空应用和带图应用劣化的阶段基本一致。相比3568,除了正常的CPU耗时增加之外,IO耗时明显增加。
将耗时多的阶段进一步分解分析,发现主要是动态库和资源的加载耗时劣化。
主阶段 |
子阶段 |
耗时(ms) |
备注 |
MainThread::HandleLaunchApplication |
Global::Resource::ResourceManagerImpl::AddResource |
16.936 |
加载hapResource |
Global::Resource::ResourceManagerImpl::UpdateResConfig |
23.398 |
SetLocaleInfo、SetColorMode、SetInputDevice、SetDeviceType |
|
StageModel LoadAllExtensions |
82.612 |
/system/lib/extensionability /system/lib/libdatashare_ext_ability_module.z.so /system/lib/libworkschedextension.z.so /system/lib/libaccessibility_extension_module.z.so /system/lib/libwallpaper_extension_module.z.so |
|
AbilityThread::HandleAbilityTransaction |
Global::Resource::ResourceManagerImpl::UpdateResConfig |
28.498 |
/system/lib/module/libhilog.z.so onStart阶段SetScreenDensity、SetDirection |
UIContentImpl::CommonInitialize |
Global::Resource::ResourceManagerImpl::AddResource |
40.197 |
LoadThemes阶段ResourceAdapterImpl::Init中AddResource,添加resources.index |
Global::Resource::ResourceManagerImpl::UpdateResConfig |
26.49 |
LoadThemes阶段ResourceAdapterImpl::Init中UpdateResConfig |
|
PushPage |
Global::Resource::ResourceManagerImpl::AddResource |
41.45 |
PipelineContext::FlushBuild阶段 |
Global::Resource::ResourceManagerImpl::UpdateResConfig |
22.715
|
|
|
Global::Resource::ResourceManagerImpl::UpdateResConfig |
20.243 |
|
从trace上也能明显看到资源加载的耗时。
IO速率对比
先看看驱动的IO速率。编译开源工具fio测试IO速率,对比两个内核的驱动IO速率(原厂4.14内核和自行移植到OpenHarmony的5.10内核)。
5.10内核:随机读43.9MB/s,随机写43.9MB/s,顺序读44.4MB/s,顺序写43.4MB/s
4.14内核:随机读69.9MB/s,随机写6.4MB/s,顺序读156.1MB/s,顺序写47.3MB/s
发现,IO读取速率相差大,所以驱动能力没有完全移植过来。
优化措施
提升驱动IO速率
系统优化措施
由于原厂驱动只有伙伴才有,IO速率的移植伙伴没搞定。我们同步尝试系统层面的优化。
IO速率从系统层面提升不了,但对于IO加载类问题,系统还是可以有一些措施的,比如可以采用预加载或者异步加载。
优化效果
不仅超越了Android,还是达到了我们的挑战目标。
分类 |
特性 |
指标名称 |
单位 |
达标值 |
挑战值 |
Android对标数据 |
测试数据 |
测试数据 |
测试数据 |
测试数据 |
应用 |
应用启动 |
空应用冷启动时长 |
ms |
950 |
800 |
1145 |
1068 |
1067 |
864 |
769 |
应用 |
应用启动 |
首页带图应用冷启动时长 |
ms |
1100 |
950 |
1301 |
1584 |
1200 |
1101 |
1096 |
开机内存优化
得益于OpenHarmony灵活可配置的架构,对不必要的子系统和部件进行了裁剪,内存占用就大幅优于Android。
分类 |
特性 |
指标名称 |
单位 |
达标值 |
挑战值 |
Android对标数据 |
测试数据 |
测试数据 |
整机 |
开机内存 |
开机后静置使用内存 |
M |
512 |
480 |
使用内存:472M |
使用内存:410M |
使用内存:377M |
优化结果总结
1、系统性能KPI优于Android
2、应用交互体验优于Android
指标名称 |
单位 |
A系统数据 |
测试数据 |
测试数据 |
空应用冷启动时长 |
ms |
1145 |
1068 |
769 |
首页带图应用冷启动时长 |
ms |
1301 |
1584 |
1096 |
纯文本界面切换时长 |
ms |
502 |
569 |
436 |
带图界面切换时长 |
ms |
669 |
935 |
434 |
带图列表页面滑动帧率 |
fps |
56 |
12.1 |
58.5 |
开机后静置使用内存 |
M |
使用内存:472M |
使用内存:410M |
使用内存:375M |
更多推荐
所有评论(0)