背景

伙伴反馈,设备操作卡顿,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


MemTotal:887M

剩余内存: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对标数据

测试数据
(1127版本)

测试数据
(1212版本)

测试数据
(1221版本)

应用

帧率

带图列表页面滑动帧率

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对标数据

测试数据
(1127版本)

测试数据
(1212版本)

测试数据
(1221版本)

测试数据
(0104版本)

应用

帧率

带图列表页面滑动帧率

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对标数据

测试数据
(1127版本)

测试数据
(1212版本)

应用

应用启动

空应用冷启动时长

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)
较GPU未合成前

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发现:
该函数耗时偏差主要体现在JsAbility::DoOnForeground上,具体细化,耗时主要是scene_->Init、scene_->GetMainWindow()->SetUIContent和GoForeground

UIContentImpl::CommonInitialize

101.358

211.204

109.846

127.648

-83.556

经分析trace发现:
该函数耗时偏差主要体现在Init、GetDefaultDisplay阶段、CreateView阶段、SetView阶段

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对标数据

测试数据
(1127版本)

测试数据
(1212版本)

测试数据
(1221版本)

测试数据
(0105版本)

应用

应用启动

空应用冷启动时长

ms

950

800

1145

1068

1067

864

769

应用

应用启动

首页带图应用冷启动时长

ms

1100

950

1301

1584

1200

1101

1096

 开机内存优化

得益于OpenHarmony灵活可配置的架构,对不必要的子系统和部件进行了裁剪,内存占用就大幅优于Android。

分类

特性

指标名称

单位

达标值

挑战值

Android对标数据

测试数据
(1127版本)

测试数据
(1212版本)

整机

开机内存

开机后静置使用内存

M

512

480

使用内存:472M
剩余内存:415M
MemTotal:887M

使用内存:410M
剩余内存:480M
MemTotal:890M

使用内存:377M
剩余内存:513M
MemTotal:890M

 

优化结果总结

1、系统性能KPI优于Android

2、应用交互体验优于Android

指标名称

单位

A系统数据

测试数据
(1127版本)

测试数据
(0306版本)

空应用冷启动时长

ms

1145

1068

769

首页带图应用冷启动时长

ms

1301

1584

1096

纯文本界面切换时长

ms

502

569

436

带图界面切换时长

ms

669

935

434

带图列表页面滑动帧率

fps

56

12.1

58.5

开机后静置使用内存

M

使用内存:472M
剩余内存:415M
MemTotal:887M

使用内存:410M
剩余内存:480M
MemTotal:890M

使用内存:375M
剩余内存:515M
MemTotal:890M

 

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐