性能测试-流畅度指标、数据的获取

        上节我们谈到流畅度作为用户能够直观感受到Android系统性能高低的方面,主要可以包括launcher中待机界面的滑动流畅度、主菜单界面界面滑动的流畅度、待机界面和主菜单界面切换的流畅程度;还有就是在横竖屏切换的流畅度,应用方面主要就是应用打开的响应时间,使用过程中的流畅度,中断切换重新进入等方面的流畅度。

        这段时间主要收集了一些现有资料,流畅度中指标主要是(FPS:系统合成帧率、Aggregate frame stats:应用跳帧次数、幅度、Jankiness count:(估算)应用跳帧次数、Max accumulated frames:(估算)应用跳帧幅度、Frame rate:应用绘制帧率、SM:应用绘制轮询频率、Skipped frames:应用跳帧次数、幅度),局限于本人的知识水平,探究分析将主要针对于FPS方面的数据,后续将继续补充~

        针对于launcher模块,初步我们收集了界面滑动和切换界面的响应时间,工具主要用的是高速摄像机(120帧/s),这样每个场景尝试收集了5组数据,除去一组最大值和最小值,最终的三组求平均值即为该场景的响应时间,这种方式所测量的方法很大程度上依靠于个人的主管程度和测量时所理解的开始时间和结束时间,需要统一标准开始时间后这样测出的响应时间和竞品的数据才有可比性和可分析性;

        对于FPS数据的采集,第一我们采用的是adb命令行的方式,主要使用的命令行包括adb shell dumpsys gfxinfo package_name >FPS.txt 这条命令主要采集的是近128帧数据的渲染时间,每一帧数据包括有draw prepared process execute这四部分,之前可能只有三部分数据一帧,目前新添加上数据prepared数据,分别代表的含义包括:

        Draw(蓝)表示View.onDraw()方法的耗时,这部分主要是建立DisplayList对象用的,这些对象将会被转化成OpenGL命令,GPU只能读懂OpenGL命令。如果这个地方耗时比较大,说明视图比较复杂。蓝色区域代表的时间,是创建DisplayList对象的时间。

        Prepared(紫)5.1以后将UI Thread线程所做的事分成了2个线程来做:UI Thread和Render Thread。新加的Render Thread线程会将Draw过程生成的DisplayList对象转化成为OpenGL的命令,然后发送给GPU,这个时候UI Thread可以空闲下来处理下一个frame的数据。如果传送的资源过多的话这个地方耗时就比较大。紫色区域代表的时间就是UI Thread传送数据给Render Thread所用的时间。

      Process(红)红色区域代表创建OpenGL命令的时间,表示渲染引擎执行显示列表所花的时间,view越多,时间就越长。

      Execute(黄)黄色区域代表发送OpenGL命令给GPU所用的时间,表示把一帧数据发送到屏幕上排版显示实际花费的时间。其实是实际显示帧数据的后台缓存区与前台缓冲区交换后并将前台缓冲区的内容显示到屏幕上的时间。所以这个时间,一般都很短。

      一般我们将这四部分时间相加时间小于16ms定义为流畅帧,因为这样一秒时间内才能绘制出60帧以上,达到流畅的程度;若一帧渲染时间超过了16ms,这时就会出现丢帧的现象,也就是我们常看到的卡顿;具体进程的分析我们将用到traceview来分析个进程中方法的调用是否超时或调用次数(递归次数)过多影响渲染时间,此工具数据分析待以后详解;

        第二种数据获取的命令方式为adb shell dumpsys Surface Flinger --latency Package_name >FPS.txt 这种方式我们获取 的128帧数据(第一行为刷新周期),其余127帧数据分为三部分,每一列代表一部分:

   第一列:这一部分的数据表示应用程序绘制图像的时间点。

  第二列:这一部分代表的是在SF(软件)将帧提交给H/W(硬件)绘制之前的垂直同步时间。

  第三列:SF将帧提交给H/W的时间点,是H/W接受完SF发来数据的时间点,绘制完成的时间点。

       当渲染时间大于16.67,按照垂直同步机制,该帧就已经渲染超时 ;那么,如果它正好是16.67的整数倍,比如66.68,则它花费了4个垂直同步脉冲,减去本身需要一个,则超时3个; 如果它不是16.67的整数倍,比如67,那么它花费的垂直同步脉冲应向上取整,即5个,减去本身需要一个,即超时4个,可直接算向下取整 ;

       最后的计算方法思路: 执行一次命令,总共收集到了m帧(理想情况下m=128),但是这m帧里面有些帧渲染超过了16.67毫秒,算一次jank,一旦jank, 需要用掉额外的垂直同步脉冲。其他的就算没有超过16.67,也按一个脉冲时间来算(理想情况下,一个脉冲就可以渲染完一帧) 

所以FPS的算法可以变为: m / (m + 额外的垂直同步脉冲) * 60;

       通过这条命令我们所获取到的数据计算出帧率,这个应是硬件层面,也就是显示层面的刷新帧率,这与帧率之间存在着一定区别:

       刷新帧率:显卡渲染出多帧图像,是需要显示设备呈现在我们面前的。这个显示设备就是我们熟知的显示器。显示器有一个概念叫做刷新率(Windows系统在控制面板,显示里设置),是指在1秒内,重新刷新屏幕的次数。

      帧率:帧率是用来衡量显卡渲染能力的一个指标。显卡在处理图像数据时,性能越强的显卡,在均等时间内(比如1秒),渲染出的静态图像的数量(这一幅静态图像就称为一帧)。

      显示器的刷新一帧后就会产生一个垂直同步信号。当我们选择“垂直同步”(即打开垂直同步)时,显卡在渲染每一帧之前会等待垂直同步信号,只有显示器完成了一次刷新时,发出垂直同步信号,显卡才会渲染下一帧。这种情况下,显卡的渲染能力会受到显示器刷新率的制约。如果显示器刷新率是60Hz,显卡帧率最多只会达到60。

       最终,我们可以通过py脚本,可视化的窗口形式直观的显示出来,流畅度的评分可以考虑几个层面包括FPS,MFS,OKT,Frame,这样各指标所占一定比例得出的SS评分更为客观评价;数据整理和分析见下回分解。

你可能感兴趣的:(性能测试-流畅度指标、数据的获取)