ios查看帧率的软件_iOS实时流畅性监控

画面展示过程

画面的生成到展示需要经过CPU处理和GPU处理两个过程,其中CPU主要负责软件层面的工作,GPU主要负责硬件层面的工作。这中间的过程大致可以分为六个步骤:

布局 – 准备视图/图层层级,设置图层属性。

显示 – 这是图层的寄宿图片被绘制的阶段。绘制有可能涉及你的-drawRect:和-drawLayer:inContext:方法的调用路径。

准备 – 这是Core Animation准备发送动画数据到渲染服务的阶段。这同时也是Core Animation将要执行一些别的事务例如解码动画过程中将要显示的图片的时间点。

提交 – 这是最后的阶段,Core Animation打包所有图层和动画属性,然后通过IPC(内部处理通信)发送到渲染服务进行显示。

对所有的图层属性计算中间值,设置OpenGL几何形状(纹理化的三角形)来执行渲染

在屏幕上渲染可见的三角形

前五个阶段都在软件层面处理(通过CPU),只有最后一个被GPU执行。我们真正只能控制前两个阶段:布局和显示。Core Animation框架在内部处理剩下的事务,你也控制不了它。但是在布局和显示阶段,你可以决定哪些由CPU执行,哪些交给GPU去做。

这方面的细节不再过多介绍,苹果的官方文档有详细的阐述,感兴趣的同学可以看这个。

为了做到动画的平滑,一般需要以60帧每秒的速度。所以每帧画面的处理过程只有16.6ms,如果某帧处理时间超出,则可能影响到后续帧的展示,造成丢帧,丢帧过多时会造成肉眼可见的卡顿。

主流监测方案

现在主流的卡顿监控方案主要有两种:

FPS监控:通过计算主线程一段时间内的RunLoop调用次数衡量当前页面绘制的质量

主线程卡顿监控: 通过开辟一个子线程监控主线程RunLoop状态区域的耗时,检测是否发生卡顿

用到了第一种实现方案,微信读书和美团结合使用了这两种方案。

这两种方案都集中于监控主线程runloop的状态,然而在实际的测试中,我发现有时候出现明显的卡顿时,主线程的指标反馈良好。

上有人详细阐述了这个现象,详见。

正如我们在上一节所说,画面的展示不仅和CPU相关,还和GPU有很大的关系。所以,如果能对GPU的性能也做到监控,能更好的反映APP的当前性能。

实时帧率监控实现

对于CPU的监控,可以简单的创建一个CADisplayLink,计算一秒内的调用次数得到FPS数据,实现效果如下图:

很明显可以注意到GPU的帧率降低到了12帧左右,但是CPU的帧率同时也相应降低到了12帧!这种方案虽然能一定程度反映GPU性能指标,但是却无法将CPU的性能和GPU的性能指标分离。我推测造成这个问题的原因是GPU的draw call调用阻塞了当前runloop。普通的OpenGL调用不应该造成CPU和GPU之间的同步,但是一些OpenGL的操作会造成CPU和GPU之间同步现象的出现,stackOverflow上有人讨论过这个问题。

分离CPU和GPU的性能指标有两种思路:

可以通过开关关闭对GPU的监控,然而这样操作相对较麻烦

尝试将GPU的draw call放在背景线程的runloop中调用

由于GLKView是UIView的子类,在背景线程调用GLKView的方法,可能会造成不可预期的影响。或许可以考虑使用图层的方式渲染OpenGL,来规避这个问题。CAEAGLLayer看起来是一个好的解决方案。

实现后效果如下:

ios查看帧率的软件_iOS实时流畅性监控

可以看到CPU和GPU的性能指标如预期一般成功分离了。

参考链接

相关资源:暗组苹果找回助手(找回丢失Iphone手机)v1.0中文绿色版-其它代码类…

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2020年11月18日
下一篇 2020年11月18日

相关推荐