视图渲染、CPU和GPU卡顿原因及其优化方案

 视图渲染、CPU和GPU卡顿原因及其优化方案

视图渲染过程:

1、CPU 计算好显示内容提交到 GPU

2、GPU 渲染完成后将渲染结果放入帧缓冲区

3、视频控制器会按照 VSync 信号逐行读取帧缓冲区的数据,经过可能的数模转换传递给显示器显示

视图渲染、CPU和GPU卡顿原因及其优化方案


在最简单的情况下,帧缓冲区只有一个,这时帧缓冲区的读取和刷新都都会有比较大的效率问题。为了解决效率问题,显示系统通常会引入两个缓冲区,即双缓冲机制。在这种情况下,GPU 会预先渲染好一帧放入一个缓冲区内,让视频控制器读取,当下一帧渲染好后,GPU 会直接把视频控制器的指针指向第二个缓冲器。如此一来效率会有很大的提升。

为了解决这个问题,GPU 通常有一个机制叫做垂直同步(简写也是 V-Sync),当开启垂直同步后,GPU 会等待显示器的 VSync 信号发出后,才进行新的一帧渲染和缓冲区更新。这样能解决画面撕裂现象,也增加了画面流畅度,但需要消费更多的计算资源,也会带来部分延迟。

那么目前主流的移动设备是什么情况呢?从网上查到的资料可以知道,iOS 设备会始终使用双缓存,并开启垂直同步。而安卓设备直到 4.1 版本,Google 才开始引入这种机制,目前安卓系统是三缓存+垂直同步。

卡顿产生的原因

视图渲染、CPU和GPU卡顿原因及其优化方案


在 VSync 信号到来后,系统图形服务会通过 CADisplayLink 等机制通知 App,App 主线程开始在 CPU 中计算显示内容,比如视图的创建、布局计算、图片解码、文本绘制等。随后 CPU 会将计算好的内容提交到 GPU 去,由 GPU 进行变换、合成、渲染。随后 GPU 会把渲染结果提交到帧缓冲区去,等待下一次 VSync 信号到来时显示到屏幕上。由于垂直同步的机制,如果在一个 VSync 时间内,CPU 或者 GPU 没有完成内容提交,则那一帧就会被丢弃,等待下一次机会再显示,而这时显示屏会保留之前的内容不变。这就是界面卡顿的原因。

从上面的图中可以看到,CPU 和 GPU 不论哪个阻碍了显示流程,都会造成掉帧现象。所以开发时,也需要分别对 CPU 和 GPU 压力进行评估和优化。

CPU和GPU卡顿原因、优化方案:

一、CPU

1、对象操作

1)、对象创建

对象的创建会分配内存、调整属性、甚至还有读取文件等操作,比较消耗 CPU 资源。尽量用轻量的对象代替重量的对象,可以对性能有所优化。比如 CALayer 比 UIView 要轻量许多,那么不需要响应触摸事件的控件,用 CALayer 显示会更加合适。如果对象不涉及 UI 操作,则尽量放到后台线程去创建,但可惜的是包含有 CALayer 的控件,都只能在主线程创建和操作。通过 Storyboard 创建视图对象时,其资源消耗会比直接通过代码创建对象要大非常多,在性能敏感的界面里,Storyboard 并不是一个好的技术选择。

尽量推迟对象创建的时间,并把对象的创建分散到多个任务中去。尽管这实现起来比较麻烦,并且带来的优势并不多,但如果有能力做,还是要尽量尝试一下。如果对象可以复用,并且复用的代价比释放、创建新对象要小,那么这类对象应当尽量放到一个缓存池里复用。

2)、对象调整

对象的调整也经常是消耗 CPU 资源的地方。这里特别说一下 CALayer:CALayer 内部并没有属性,当调用属性方法时,它内部是通过运行时 resolveInstanceMethod 为对象临时添加一个方法,并把对应属性值保存到内部的一个 Dictionary 里,同时还会通知 delegate、创建动画等等,非常消耗资源。UIView 的关于显示相关的属性(比如 frame/bounds/transform)等实际上都是 CALayer 属性映射来的,所以对 UIView 的这些属性进行调整时,消耗的资源要远大于一般的属性。对此你在应用中,应该尽量减少不必要的属性修改。

当视图层次调整时,UIView、CALayer 之间会出现很多方法调用与通知,所以在优化性能时,应该尽量避免调整视图层次、添加和移除视图。

3)、对象销毁

对象的销毁虽然消耗资源不多,但累积起来也是不容忽视的。通常当容器类持有大量对象时,其销毁时的资源消耗就非常明显。同样的,如果对象可以放到后台线程去释放,那就挪到后台线程去。这里有个小 Tip:把对象捕获到 block 中,然后扔到后台队列去随便发送个消息以避免编译器警告,就可以让对象在后台线程销毁了。

2、排版

1)、布局计算

用户喜欢...

虚幻引擎学习之路:渲染模块之全局光照明

之前为大家分别介绍了Unreal 4引擎中渲染模块的光照系统、材质系统和相机图像后处理,在本篇文章中,我们将为大家介绍渲染模块的全局光照明这部分内容。 在此,特别感谢Unreal中国团队对...


虚幻引擎学习之路:渲染模块之材质系统

接上文:虚幻引擎学习之路:渲染模块之光照系统 在本篇文章中,我们继续介绍渲染模块的另一重要部分:材质系统。 虚幻引擎学习之路:材质系统 材质描述了场景中物体与光照进行交互的...


图形渲染管线 The Graphics Rendering Pipeline

这篇文章是解析计算机图形学界“九阴真经总纲”一般存在的《Real-Time Rendering 3rd》系列文章的第二篇。将带来RTR3第二章内容“Chapter 2 The Graphics Rendering Pipeline 图形渲染管线”的总结、概括与...


学习OpenGL ES之渲染到纹理

本文将介绍渲染到纹理技术。之前的例子都是将3D物体渲染到屏幕上,在iOS中GLKView为我们做好了渲染到屏幕的所有准备工作,我们只需要调用Open GL ES的绘制方法就可以轻松的渲染到屏幕。那...


STM32单片机USB传输数据时出现卡顿现象

这几个客户问题现象基本差不多,采用 STM32 作为 Device 设备,在与上位机或者 PC 端双向通讯一段时间后,从 Device 端到 Host 端的数据能够正常,而从 Host 端到 Device 端的数据异常,也就是说,...


夏普全面屏新旗舰360°渲染:小米MIX2劲敌

这款手机的设计思路似乎和即将发布的小米MIX2相似,顶部无预留,底部仅保留LOGO、前置摄像头和长条形呼吸灯,屏占...


大神自制夏普S3渲染图 长这样只能买了

配置方面,夏普S3采用了5.8英寸2K显示屏,搭载骁龙835处理器,拥有6GB+64/128GB内存组合,采用前置800万像素+后置1200万...


LG V30渲染图曝光:惊艳全面屏 后置平行双摄

根据此前曝光消息,配置方面,LG V30将搭载骁龙835 SoC,具有4GB RAM和64GB本地存储,还有6GB RAM和128GB本地存储的版本。...


基于OpenGL ES实现多媒体全景渲染

近几年来,VR型的多媒体变得越来越常见。在YouTube上就有很多360度视频,很多地图产品也提供全景街道图。作为开发者,我们不禁要想如何实现多媒体的全景渲染呢? 其实,渲染VR的多媒体其...


小米MIX 2的渲染图是真的吗?官方回应:P的不错

那么颜值如此之高的小米MIX 2究竟是不是真机呢?今天小米手机产品市场总监臧智渊在微博表示“P的不错”,可见以...


GPU渲染管线与shader

1、几何阶段(顶点shader处理这部分) 模型坐标空间-世界坐标空间-观察坐标空间-屏幕坐标空间 其中从观察空间 到 屏幕空间需要经过3步(CVV单位立方体,规范立方体) a用透视变换矩阵把顶点从视...


小米7渲染图再曝 骁龙845配备屏下指纹识别

配置方面,小米7采用了5.7英寸18:9全面屏,搭载骁龙845处理器,6/8GB内存+64/128GB闪存,前置1600万像素,后置双1600万像...


LG Q6渲染图曝光 金属机身配置中端疑似G6降级版

LG Q6被视为旗舰手机LG G6的迷你版本,有传闻称该机采用了一块分辨率达1080 x 1920的5.4吋Full Vision显示屏(G6采用的则是...


魅族PRO 7渲染图谍照再曝光:双屏设计被证实

众所周知,配件厂商一般都可以提前一段时间拿到新机或新机资料,照着外观做配件,消息准确度还是比较高的。因...


【西川善司】3D图形的概念和渲染管线(1)

翻译 Trace 校对注解 千里马肝 3D图形的概念和渲染管线(Render Pipeline) 前面介绍了3D图形历史,接下来要解说的是3D图形的处理流程。 3D图形管线的流程图 图1是3D图形的流程模型。这个虽然是...


(原)[OpenGL ES 02]OpenGL ES渲染管线与着色器

前言 在前文《[OpenGL ES 01]OpenGL ES之初体验》中我们学习了如何在 iOS 平台上设置OpenGL ES 环境,主要是设置 CAEAGLLayer 属性,创建 EAGLContext,创建和使用 renderbuffer 和 framebuffer,并知道如何清屏。...