GPU加速在前端的应用

1,概述

GPU(Graphics Processing Unit) 图形处理单元,又称图形处理器,是我们所周知的显卡的核心部件,是显卡的“心脏”。

按照字面意思我们可以猜测得到GPU是和显示(图像相关)的,再结合CPU一起理解,我们可以推测GPU也是有运算(计算能力的)。

GPU到底有何作用和能力呢?

GPU是专为复杂数学运算和几何运算而设计的芯片,它的用途我们平常所周知的就是用于图形图像处理(显卡),但是实际用途不仅仅如此(依托GPU强大的计算能力(多强大下面会讲)进行挖矿、机器学习算法)。

2,CPU与GPU

上面我们知道GPU可以处理复杂的运算,处理能力比CPU很强,那到底有多强呢,有个数据可以说明:

现在主流的i7处理器的浮点计算能力是主流的英伟达GPU处理器浮点计算能力的1/12。

为什么GPU的处理能力比CPU强,这就需要从逻辑结构来分析一下。

其中Control是控制器,ALU是算术逻辑单元、Cache是CPU内部缓存、DRAM是内存。从上图我们可以知道GPU将更多的空间(晶体管)用作执行单元,而不是像CPU那样用作复杂的控制单元和缓存(CPU需要同时很好的支持并行和串行操作,需要很强的通用性来处理各种不同的数据类型,同时又要支持复杂通用的逻辑判断,这样会引入大量的分支跳转和中断的处理。这些都使得CPU的内部结构异常复杂,计算单元的比重被降低了),实际来看CPU的芯片控件5%是ALU,而GPU则高达40%(GPU面对的则是类型高度统一的、相互无依赖的大规模数据和不需要被打断的纯净的计算环境。因此GPU的芯片比CPU芯片简单很多),这也就是为啥GPU运算能力超强的原因。

3,GPU加速

上面我们对比了GPU和CPU在逻辑结构上的差异,从中我们知道得益于GPU密集的逻辑处理单元(高并行结构),GPU适合对高密集的数据进行并行处理,CPU执行计算任务时,一个时刻只能处理一个数据,不存在真正意义上的并行(在多核CPU中,真正的并行有了可能。即在多线程设计中一部分可用来处理前台任务,一部分可用来处理后台任务,实现真正意义上的并行。),而GPU具有多个处理器核,在一个时刻可以并行处理多个数据,真正意义上实现了高并行。我们所说的GPU加速其实原理就是利用了GPU的高并行计算能力,比如我们在前端中利用GPU来处理复合图层(像素密集型)进行“加速”。

GPU采用流式并行计算模式,可对每个数据进行独立的并行计算,所谓“对数据进行独立计算”,即,流内任意元素的计算不依赖于其它同类型数据,例如,计算一个顶点的世界位置坐标,不依赖于其他顶点的位置。而所谓“并行计算”是指“多个数据可以同时被使用,多个数据并行运算的时间和1个数据单独执行的时间是一样的”。

4,GPU加速在前端的应用

首先我们要知道为什么要用(开启)GPU加速(硬件加速), 然后我们才能去探讨如何以及怎么样去应用GPU加速。

4.1, 为什么要开启GPU加速。

回答这个问题前我们可以先来看两个CSS Animation(都是应用了帧动画,但是一个没有开启GPU加速,一个开启了GPU加速)

没有开启:

开启:


通过两个动画对比,第一个动画运行会有卡顿(没有达到60fps),而第二个则perfect(not reflow,not always repaint when animation running),运行顺畅。

那么为什么要开启GPU加速呢,答案很明显,为了体验,用户体验!!!

4.2,如何在前端中应用GPU加速

首先我们先回顾下前端页面渲染过程。

再结合下浏览器的内部结构看下

在第一张图中我们知道,页面最终呈现是需要经过一个我们通常不是很关注的步骤--绘制,实际上在Painting之后Display之前有还有一个步骤--Composite(渲染层合并)。

结合第二张图,Painting(绘制)的具体工作是由浏览器UI后端部分负责完成的,在Painting阶段,会调用引擎的paint api(canvas会调用draw api)进行像素级信息计算与绘制,像素级信息具体表现为帧信息(图层),浏览器会将各层的信息发送给GPU(GPU进程:最多一个,用于3D绘制等),GPU会将各层合成(composite),显示在屏幕上。接下来我们具体来看来看下Composite干了什么?

概括下Composite干了什么:页面中 DOM 元素的绘制是在多个层上进行的。在每个层上完成绘制过程之后,浏览器会将所有层按照合理的顺序合并成一个图层,然后显示在屏幕上。对于有位置重叠的元素的页面,这个过程尤其重要,因为一旦图层的合并顺序出错,将会导致元素显示异常。

我们经常说要避免回流(reflow:重新计算元素几何尺寸和位置),为什么可以避免呢,这是因为在实际场景下,大致会出现三种常见的渲染流程(Layout和Paint步骤是可避免的):

But what and why? 这就需要我们继续深挖下浏览器(webkit内核)绘制工作。

上文提到了层的概念,首先我们先来了解下层是什么鬼?

从上图(结合浏览器的基本渲染过程图)我们可以知道层的产生过程,渲染树最终会转换成层树(Layer tree),从上图我们也可以知道其实chrome(webkit)有两种类型的层。

RenderLayers 渲染层,这是负责对应 DOM 子树

GraphicsLayers 图形层,这是负责对应 RenderLayers子树。

在 DOM 树中每个节点都会对应一个 LayoutObject,当他们的 LayoutObject 处于相同的坐标空间时,就会形成一个 RenderLayers ,也就是渲染层。RenderLayers 来保证页面元素以正确的顺序合成,这时候就会出现层合成(composite),从而正确处理透明元素和重叠元素的显示。

某些特殊的渲染层会被认为是合成层(Compositing Layers),合成层拥有单独的 GraphicsLayer,而其他不是合成层的渲染层,则和其第一个拥有 GraphicsLayer 父层公用一个。

而每个GraphicsLayer(合成层单独拥有的图层) 都有一个 GraphicsContext,GraphicsContext 会负责输出该层的位图,位图是存储在共享内存中,作为纹理上传到 GPU 中,最后由 GPU 将多个位图进行合成,然后显示到屏幕上,到这里终于道出了浏览器页面渲染呈现GPU的存在,再结合我们上文提到的GPU对于密集型数据(比如图像像素级)的运算能力,我们也差不多说明了GPU加速为何可以在前端中进行应用 --让需要进行复杂动画的元素(或所在元素)单独拥有一个合成图层。

在回答怎么变成合成层之前,我们看下合成层的优点:

合成层的位图,会交由 GPU 合成,比 CPU 处理要快

当需要 repaint 时,只需要 repaint 本身,不会影响到其他的层

对于 transform 和 opacity 效果,不会触发 layout 和 paint

然后我们再看下如何变成合成层,如何应用GPU加速(硬件加速):

3D 或透视变换(perspective transform) CSS 属性

使用加速视频解码的 <video> 元素 拥有 3D

(WebGL) 上下文或加速的 2D 上下文的 <canvas> 元素

混合插件(如 Flash)

对自己的 opacity 做 CSS动画或使用一个动画变换的元素

拥有加速 CSS 过滤器的元素

元素有一个包含复合层的后代节点(换句话说,就是一个元素拥有一个子元素,该子元素在自己的层里)

元素有一个z-index较低且包含一个复合层的兄弟元素(换句话说就是该元素在复合层上面渲染)

提升合成层的最好方式是使用 CSS 的 will-change属性。 will-change 可以设置为opacity、transform、top、left、bottom、right。

注意事项:

提升到合成层后合成层的位图会交GPU处理,但请注意,仅仅只是合成的处理(把绘图上下文的位图输出进行组合)需要用到GPU,生成合成层的位图处理(绘图上下文的工作)是需要CPU。

当需要repaint的时候可以只repaint本身,不影响其他层,但是paint之前还有style, layout,那就意味着即使合成层只是repaint了自己,但style和layout本身就很占用时间。

仅仅是transform和opacity不会引发layout 和paint,那么其他的属性不确定。

最后,也说说缺点或者说容易踩坑的地方(要学会权衡、学会克制):

合成层占用内存的问题。

层爆炸,由于某些原因可能导致产生大量不在预期内的合成层,虽然有浏览器的层压缩机制,但是也有很多无法进行压缩的情况,这就可能出现层爆炸的现象(简单理解就是,很多不需要提升为合成层的元素因为某些不当操作成为了合成层)。解决层爆炸的问题,最佳方案是打破 overlap 的条件,也就是说让其他元素不要和合成层元素重叠。简单直接的方式:使用3D硬件加速提升动画性能时,最好给元素增加一个z-index属性,人为干扰合成的排序,可以有效减少创建不必要的合成层,提升渲染性能,移动端优化效果尤为明显。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350