GPU(Graphics Processing Unit),也即显卡,是一种专门在个人电脑、工作站、游戏机和一些移动设备(如平板电脑、智能手机等)上作图像运算工作的微处理器。它已经是个人PC和移动设备上不可或缺的芯片,有界面有显示的地方,一般就离不开它。高清电视、智能手机、个人电脑。
GPU的产生是为了解决图形渲染效率的问题,但随着技术进步,GPU越来越强大,尤其是shader出现之后(这个允许我们在GPU上编程),GPU能做的事越来越多,不再局限于图形领域,也就有人动手将其能力扩展到其他计算密集的领域,这就是GP(General Purpose)GPU。
考虑到当下,图形领域的技术人员对GPU已经是很熟悉了,其他那些关心GPU的,无非是向往GPU的强大并行运算能力,想利用它做通用计算的,因此,本文会特别提GPGPU。
大致可以分为三层:
1. 图形引擎/算法库,比如:Cocos2D, Ogre, Unity3D, Caffe等.
2. 图形标准API,比如:D3D, OpenGL, VulKan, OpenCL, CUDA
3. 不同型号的GPU,如Tesla, Iris, GTX, Mali, PowerVR等
硬件与驱动
在个人PC、游戏主机及服务器市场,主要是NVIDIA和AMD两强争霸,传统的图形渲染上,不分伯仲;通用计算方面,由于NVIDIA先行了一步,推出CUDA,生态圈已成,拥有绝对优势;不妨看今年据说要爆发的VR(虚拟现实)上,两边的成绩如何。
嵌入式设备市场上,GPU品种要繁多一些,论第一还是首推iphone所采用的powerVR(Imagination公司所产),其次是高通的Adreno系列(如小米、三星S7),继而Arm的mali系列(海思自用图芯吃亏之后,改用mali系列,图形能力脱胎换骨【但还是相对弱势】,不过P6、D2给消费者留下的图形能力不行的阴影至今仍在)。其他份额较少的gpu就不罗列了。
一般来说,gpu的驱动框架类似下图:
一般而言,应用开发者不会直接去调用图形标准API,而是使用图形引擎/算法库。原因如下:
1、图形标准API非常繁琐难用,需要习惯GPU编程的思想,有必要做适度封装,减轻上层应用的开发难度。
2、如上文所述,图形标准有多种,且不同硬件对同一标准的支持情况也不一定相同,有必要做一个中间层,专门去处理这些问题。
3、一些图形图像算法需要较强的专业知识,得用专业人才去编写。
图形引擎
应用开发者开发界面时,主要是用操作系统提供的View框架。为支持这个框架,操作系统都会实现一套2D引擎,开发者间接使用了图形引擎。
- Android应用间接使用了Android的hwui引擎。
- 要求界面炫酷的应用,典型如游戏,会去用一些3D引擎。目前手游上主流的游戏引擎是 Unity3D和cocos2D,unity3D免费但不开源,cocos2D是做了捕鱼达人游戏的公司公布并开源的。PC游戏方面,以收费商业引擎为主,且一般是基于D3D(这就是为什么Linux、类linux系统下游戏那么少),典型如虚幻引擎,特效强大。
- ogre是主要用于PC的久负盛名的开源引擎,支持OpenGL,完美时空基于ogre做过游戏。
图形引擎多种多样,这里仅仅是列了很少一部分,毕竟是个大坑,只能简单提一下。
通用计算引擎所见的主要是
1. ArrayFire,主页:http://arrayfire.com/。它提供了一系列用OpenCL/Cuda加速的算法库,并提供方便的接口去开发GPU加速的算法。
2. caffe是工业上最常用的深度学习框架,支持多台装配NVIDIA的服务器同时进行深度学习。
3. OpenCV 是一个庞大的图像算法库,cl-opencv对其核心算法基于OpenCL作了加速。
4. PG-Storm 则据说是用 GPU加速的 postsql,具体没看过,SQL查询中的变长字符串处理是GPU优化的难点,以前看过的demo都回避了这一问题,不知道这个是否解决了。
抛开具体的硬件,标准,以及引擎来说,GPU本身代表着和CPU不一样的编程思想:CPU好比几个高智商精英,什么都能做且做得快;而GPU就是一大群低学历农民工,每个人可以做的有限,也不快,但人数优势决定其整体速度完爆精英们。
GPU编程,就像指挥一大群蚂蚁,有几个通用原则:
1、让蚂蚁们做的工作量尽可能相等,因为你要等所有蚂蚁都完成才能进行下一步。
2、不要在意每一只蚂蚁的工作细节,请关注你给蚂蚁准备的粮食。(GPU编程的主要工作是配置参数)
3、蚂蚁们所在的世界和你的世界有矩离,你要教导它们做事(提供shader或kernel),向它们喊话(触发执行API),并提供做事的资源(内存数据传到显存)。
管线
管线是GPU上做图形渲染编程最为重要的概念,GPU就像一个炒菜机,程序员要做的主要事情是给它配原料,至于翻滚、加热等工序,不在程序员的控制之内。 参考:
http://www.360doc.com/content/13/0107/18/9934052_258805453.shtml
简单的记法:
顶点——图元——光栅化——着色
形与色
图形渲染的基本思想就是先定形,再定色。
数据并行与批量化
使用GPU加速算法,务必做到
1. 批量化处理:只处理1条或1行数据,调用GPU接口的交互时间会远远超出计算时间。
2. 减少交流:
这里的交流,一方面指的是CPU与GPU之间的数据传输,另一方面指调触发运算的API。
从事SOC开发的工作时,对此做了许多尝试均告失败。移动端的通用GPU计算实在是很难有进展的一件事情,首先,受限于可怜的GPU性能及弱爆了的内存传输带宽,GPU加速往往被多线程+neon完爆;其次,移动端作密集运算的场景着实有限,最需要运算的也就相机模块与图像编解码,但这么有限的场景厂商完全可以上DSP/ISP,GPU在这时并没太大优势。目前而言,在移动端做优化,主要还是运用OpenGL和neon。
然而随着普适计算、情景智能、图像识别的发展,移动端的通用计算将会变得越来越有意义,更快更准确的机器学习算法的使用,可以让手机更智能。
目前的分布式计算框架,通用型的如Hadoop、Spark、flink等都是只能利用CPU的(虽然也可以用GPU,但用起来很麻烦且兼容性不好)。
用上了 GPU 的,主要是特定设备上跑固定算法(Deep Learning),不具备通用性, 以致于几乎Tesla就是DL的代表.
若有一个通用的分布式异构计算框架,可以大幅降低机器学习、图像处理、视频制作等计算密集业务在时间和机器上的消耗,其价值是非常大的。
此外,基于此可以设计分布式GPU数据库,大大提升查询的性能。
参考文章:
1. GPU与GPGPU泛谈