图片和图形之使用Profile GPU渲染进行分析(19)

原文

概要


该 分析GPU渲染工具表明渲染管线的每个阶段需要渲染一帧的相对时间。这些知识可以帮助您识别流水线中的瓶颈,以便您可以知道要优化哪些内容以提高应用的渲染性能。

本页简要说明了每个管道阶段发生的情况,并讨论了可能导致瓶颈的问题。在阅读本页面之前,您应该熟悉配置文件GPU渲染中提供的信息 。此外,要了解所有阶段如何组合在一起,查看 渲染管道的工作方式可能会有帮助 。

视觉表现


Profile GPU渲染工具以图形的形式显示阶段及其相对时间:彩色直方图。图1显示了这种显示器的一个例子。
图片和图形之使用Profile GPU渲染进行分析(19)
图1.配置文件GPU渲染图
配置文件GPU渲染图中显示的每个垂直条的每个段代表管道的一个阶段,并使用条形图中的特定颜色突出显示。图2显示了每种显示颜色含义的关键。
图片和图形之使用Profile GPU渲染进行分析(19)
图2.配置文件GPU渲染图图例

一旦您了解了每种颜色的标志,就可以针对您的应用的特定方面尝试优化其渲染性能

阶段及其含义


本节将说明在图2中对应于颜色的每个阶段发生的情况,以及要注意的瓶颈原因。

Input handling

管道的输入处理阶段测量应用程序处理输入事件的时间。此度量指示应用程序花费多长时间执行代码,作为输入事件回调的结果。

当这个segment很大时

在这个区域中的高值通常是由于工作过多或者在输入处理程序事件回调内部发生太复杂的工作而造成的。由于这些回调总是在主线程上发生,所以此问题的解决方案专注于直接优化工作,或将工作卸载到不同的线程。

还值得注意的是, RecyclerView 滚动可以出现在这个阶段。 RecyclerView 当它消耗触摸事件时立即滚动。因此,它可以膨胀或填充新的项目视图。出于这个原因,尽可能快地完成此操作非常重要。Traceview或Systrace等分析工具可以帮助您进一步调查。

Animation

动画阶段向您显示评估所有在该框架中运行的动画制作者需要多长时间。最常见的动画师 ObjectAnimator, ViewPropertyAnimator和 转换。

当这个segment很大时

这个区域的高值通常是由于动画的某些属性改变而正在执行的工作的结果。例如,抛动画,其滚动的ListView或 RecyclerView,导致大量视图通货膨胀和人口的。

Measurement/layout

为了让Android在屏幕上绘制视图项目,它会在视图层次结构中的布局和视图中执行两个特定的操作。

首先,系统测量视图项目。每个视图和布局都具有描述屏幕上对象大小的特定数据。有些视图可以具有特定的大小; 其他人的大小适应父级布局容器的大小

其次,系统列出观看项目。系统计算子视图的大小后,系统可以继续进行布局,调整大小并将视图定位在屏幕上。

系统不仅对要绘制的视图执行度量和布局,而且还对这些视图的父层次结构执行测量和布局,一直到根视图。

当这个segment很大时

如果您的应用在这一领域花费了大量时间,那么通常是由于需要布置的视图数量庞大,或者您的层次结构中的错误位置存在 双重征税等问题 。无论在哪种情况下,寻址性能都涉及 提高视图层次结构的性能。

您已添加 onLayout(boolean, int, int, int, int)或 onMeasure(int, int) 可能导致性能问题的代码。Traceview和 Systrace可以帮助您检查调用堆栈以识别您的代码可能存在的问题。

Draw

绘制阶段将视图的渲染操作(例如绘制背景或绘图文本)转换为本地绘图命令的序列。系统将这些命令捕获到显示列表中。

绘制条记录完成将命令捕获到显示列表所需的时间,对于需要在此帧的屏幕上更新的所有视图。测量的时间适用于您添加到应用中UI对象的任何代码。这样的代码的例子可以是 onDraw(), dispatchDraw()和各种draw ()methods属于类的子类 Drawable的类。

当这个segment很大时

简而言之,您可以将此度量标准理解为显示onDraw() 为每个无效视图运行所有呼叫需要多长时间 。此度量包括花费调度绘制命令给儿童的任何时间和可能存在的绘图。出于这个原因,当你看到这个柱状图时,原因可能是一堆视图突然失效。无效使得有必要重新生成视图的显示列表。或者,冗长的时间可能是一些自定义视图的结果,这些视图在其onDraw()方法中具有一些极其复杂的逻辑 。

Sync/upload

同步和上载指标表示在当前帧期间将位图对象从CPU内存传输到GPU内存所需的时间。

作为不同的处理器,CPU和GPU具有专用于处理的不同RAM区域。当您在Android上绘制位图时,系统会在GPU将其呈现到屏幕之前将位图传输到GPU内存。然后,GPU缓存位图,以便系统不需要再次传输数据,除非纹理从GPU纹理缓存中被逐出。

注意:在棒棒糖设备上,这个阶段是紫色的。

当这个segment很大时

帧之前,所有资源都需要驻留在GPU内存中,然后才能用于绘制帧。这意味着此度量的高价值可能意味着大量小资源负载或少量非常大的资源。一个常见的情况是应用程序显示接近屏幕大小的单个位图。另一种情况是应用显示大量缩略图。

要缩小这个栏,你可以使用如下技巧:

  • 确保您的位图分辨率不会大于它们将显示的大小。例如,您的应用应该避免将1024x1024图像显示为48x48图像。

  • 利用prepareToDraw() 在下一个同步阶段之前异步预先上传位图。

    Issue commands

    在发出命令段代表它需要发出一切必要的命令来进行绘图显示列表屏幕的时间。

为了让系统在屏幕上绘制显示列表,它将必要的命令发送给GPU。通常,它通过OpenGL ES API 执行此操作 。

此过程需要一些时间,因为系统在将命令发送到GPU之前对每个命令执行最终转换和剪切。GPU端会产生额外的开销,这会计算最终的命令。这些命令包括最终转换和额外的剪辑。

当这个segment很大时

在这个阶段花费的时间直接衡量系统在给定帧中呈现的显示列表的复杂性和数量。例如,有很多绘图操作,特别是在每个绘图基元的固有成本很低的情况下,这次可能会膨胀。例如:

for (int i = 0; i < 1000; i++)
canvas.drawPoint()

发行费用要高得多:

canvas.drawPoints(mThousandPointArray);

发布命令与实际绘制显示列表之间并不总是1:1相关。与发布命令不同的是,发布命令捕获将绘图命令发送到GPU所需的时间,绘图指标表示将发布的命令捕获到显示列表所用的时间。

这种差异的产生是因为显示列表尽可能被系统缓存。因此,在某些情况下,滚动,变换或动画要求系统重新发送显示列表,但不必从头开始实际重建它,重新获取绘图命令。结果,你可以看到一个高的“发布命令”栏,而没有看到一个高的绘图命令栏。

Process/swap buffers

一旦Android完成向GPU提交所有显示列表,系统会发出一个最终命令,告诉图​​形驱动程序它已完成当前帧。此时,司机可以最终将更新后的图像显示在屏幕上

当这个segment很大时

了解GPU与CPU并行执行工作很重要。Android系统会向GPU绘制命令,然后转到下一个任务。GPU从队列中读取这些绘图命令并对其进行处理。

在CPU发出命令的速度比GPU消耗速度快的情况下,处理器之间的通信队列可能会变满。发生这种情况时,CPU会阻塞,并等待队列中有空间放置下一个命令。这种全队列状态通常在 交换缓冲区阶段出现,因为在那时,整个帧的命令已经被提交。

缓解这个问题的关键是降低GPU上发生的工作的复杂性,与您为“问题命令”阶段所做的操作类似。

Miscellaneous

除了渲染系统执行其工作所需的时间之外,还有一组额外的工作发生在主线程中,并且与渲染无关。这项工作消耗的时间被报告为 misc时间。杂项时间通常表示可能在两个连续渲染帧之间的UI线程上发生的工作。

当这个segment很大时

如果此值很高,则很可能您的应用具有应该在另一个线程上发生的回调,意图或其他工作。诸如方法跟踪或Systrace之类的工具 可以提供对主线程上运行的任务的可见性。这些信息可以帮助您实现性能改进。

Lastest Update:2018.04.25

联系我

QQ:94297366

微信打赏:https://pan.baidu.com/s/1dSBXk3eFZu3mAMkw3xu9KQ

公众号推荐:

图片和图形之使用Profile GPU渲染进行分析(19)

转载于:https://blog.51cto.com/4789781/2120594

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值