计算机组成中,除了最核心的处理器CPU,被称之为图像处理器的GPU也是很重要的一个处理器。GPU最初的设计是为了图形处理,然而最近火热的深度学习以及大数据处理等,GPU为什么又会成为这类领域专用的处理器?
从GPU处理三维图形的渲染开始说起
早期的"3D"游戏,可以成为伪3D,只是通过在不同的角度看到不同的贴图,并不是真正的通过图形学绘制渲染。随着硬件和技术的发展,CPU的计算能力也在不断地提升,为什么还是需要单独的GPU来进行图形的渲染?CPU不能做到吗?
图形的渲染流程
现代电脑画面显示的3D画面,都是通过多边形的组合出来的。我们玩的各种3D游戏,人物的脸并不是由相机拍出来的,而是通过多边形建模创建出来的(说了我也不懂)。人物的移动、动作甚至是根据光线的变化都是通过计算机根据图形学的计算实时计算渲染出来的。
对于图像的实时计算渲染可以分为下面的5个步骤:
- 顶点处理
- 图元处理
- 栅格化
- 片段处理
- 像素操作
渲染的最终操作都会变成对像素的操作,我们都知道,我们平时所使用的屏幕分辨率不尽相同,就拿低分辨率的640x480来说,大概有30万个像素点要去处理,就像我们平时所看的视频,游戏画面想要看起来不卡顿,以每秒60帧的处理量,每秒就需要实时处理1800万个像素点的渲染。再在栅格化的处理过程中,每个像素点都要由三个流水线操作,假设每条流水线执行一条指令,那么完成一秒的指令量就要5400万,大约50M条的指令。
现在各种的高分辨率显示器乃至4K屏,综合计算下也是不小的量了,如今的CPU主频一般在3~4GHZ左右,不可能让所有的CPU资源全部消耗在图形渲染上面。
于是GPU诞生了。由于图形渲染固定的计算流程,不需要像CPU那样设计要应对各种冒险,分支预测,乱序执行的硬件电路。所以可以按照图形渲染的固定流程,专门设计用于处理响应的逻辑电路,不仅在造价更加便宜,而且功耗和计算效率方面也能大大的提示。
统一着色器架构
早期的GPU由于逻辑计算电路是固定的,整个图形渲染过程都是在硬件里面固定的管线来完成的,程序员们在加速卡上能做的事情呢,只有改配置来实现不同的图形渲染效果。如果通过改配置做不到,我们就没有什么办法了。
所以GPU应该具备一些可编程能力,即在上诉提到的图像渲染的五个步骤中的一些特别的步骤,能都自定义数据的处理算法或者操作。
图中的着色器(Shader)就是就是GPU的可编程接口。一开始只在顶点处理以及片段处理部分。所以即使提供了可编程接口,也只能对光照、亮度、颜色等等的处理。这个时候的 GPU,有两类 Shader,也就是 Vertex Shader(用于顶点处理) 和 Fragment Shader(用于片段处理)。但是这样的设计存在一个很严重的缺陷。Vertext Shader 运行的时候,Fragment Shader 停在那里什么也没干。Fragment Shader 在运行的时候,Vertext Shader 也停在那里发呆!
于是统一着色器架构(Unified Shader Architecture)就诞生了。由于Vertex Shader和Fragment Shader编排硬件所使用的指令集是一样的。那不如就在 GPU 里面放很多个一样的 Shader 硬件电路,然后通过统一调度,把顶点处理、图元处理、片段处理这些任务,都交给这些 Shader 去处理,让整个 GPU 尽可能地忙起来。这样的设计,就是我们现代 GPU 的设计,就是统一着色器架构。
正是因为 Shader 变成一个“通用”的模块,才有了把 GPU 拿来做各种通用计算的用法,也就是 GPGPU(General-Purpose Computing on Graphics Processing Units,通用图形处理器)。而正是因为 GPU 可以拿来做各种通用的计算,我们可以通过编程,在 GPU 上实现不同的算法。另一方面,现在的深度学习计算,都是超大的向量和矩阵,海量的训练样本的计算。整个计算过程中,没有复杂的逻辑和分支,非常适合 GPU 这样并行、计算能力强的架构。才有了过去 10 年深度学习的火热。
从ASIC(专用集成电路)到 TPU
在深度学习热起来之后,计算量最大的是什么呢?并不是进行深度学习的训练,而是深度学习的推断部分。所谓推断部分,是指我们在完成深度学习训练之后,把训练完成的模型存储下来。这个存储下来的模型,是许许多多个向量组成的参数。然后,我们根据这些参数,去计算输入的数据,最终得到一个计算结果。这个推断过程,可能是在互联网广告领域,去推测某一个用户是否会点击特定的广告;也可能是我们在经过高铁站的时候,扫一下身份证进行一次人脸识别,判断一下是不是你本人。
开发 ASIC 的核心原因:用特制的硬件,最大化特定任务的运行效率。
TPU就是这样的产物,尽可能的将确定的指令流程,编程固定的硬件电路。在保障响应时间的情况下,能够尽可能地提高能效比这个指标。也就是进行同样多数量的推断工作,花费的整体能源要显著低于 CPU 和 GPU。