Amiya · 2021年08月05日

GPGPU简介

Two strong oxen or 1024 chickens?

大家应该能感觉到,近些年来,CPU的发展速度远远跟不上GPU的发展速度,这里有很多因素,比如AMD的疲软,Intel主观上缺少动力,比如GPU更适合大计算量的应用,因此CPU没有太多必要提升计算能力。总之,一切都是由市场这个看不见的手来操纵。如下图,相比CPU,GPU计算能力更强,价格也更便宜。

1.jpg

GPU架构

2.jpg

我们和CPU做一个简单的类比:

  • SM(shading multiprocessors)->CPU Cores
  • Warps->hyperthreading
  • 每个warp包含32个threads,相当于SIMD
  • 每个warp内的线程执行相同的指令
  • 每个SM中有多个register,可以在warps间共享
  • Sharedmem->L1 Cache
  • Global memory->内存

和CPU之间不同的是,GPU的内存是可编程的,而CPU的缓存是不可编程的;GPU的线程管理是不可编程的,而CPU的多线程管理(SIMD)是可编程的。

这里有两点强调,第一,CPU通过Cache来解决latency,而GPU则通过并行来解决这个问题,比如原本有5s延迟,因为缓存优化,只有1s延迟,而GPU并没有缓存,所以还是有5s延迟,但因为有1000个线程同时并行,所以整体的latency就降低了。第二,就是GPU的thread scheduler,如下图,解释了为什么GPU中尽可能减少逻辑判断

3.jpg

GPGPU编程

目前,我所了解的主要有三种,Compute Shader,CUDA和OpenCL,这个是个人的优先级。在编程角度,思想上都大同小异。

首先是Global Size和LocalSize的理解,首先,我们需要计算的数据有可能是一维,二维甚至N维,对应global和local的维度。下图是一个二维数据(比如图片)对应的概念:

4.jpg

这样,我们便可以获取每一个thread对应的相对位置和全局位置,实现业务需求,如下,global(800,400),local(32,32),column line和getlocal id则是对应的索引。

5.jpg

其次,作为运算的参数和结果,我们尽可能减少内存和显存之间的转换,比如我们计算创建一张纹理(GPU),getBits(RAM),然后OpenGL渲染(GPU),在这种场景下,如果在GPGPU中的纹理能够直接对应OpenGL的Texture,则可以直接渲染,省去了FromDevice和ToDevice的操作,性能会有很大的提高。OpenCL和CUDA都支持绑定Texture对象,而Compute Shader自动支持。

整体来说,OpenCL需要自己做一个简单封装,方便调用,ComputeShader需要我们对OpenGL有不错的理解,CUDA可以通过VS自动创建,更为易用。下图是我使用三种框架做的一个Voronoi noise,github:
https://github.com/pasu/openg...

6.jpg

GPGPU的应用

首先,大规模的计算,比如CNN神经网络或者挖矿,这类应用最适合GPU,没有太多技术难点,就是怕GPU闲着,堪称GPU的996。

其次,很多CPU时代的算法并不支持并行,比如排序,如何能够实现GPU版本的算法(Bitonic sort),需要我们设计新的轮子了。

比如下面这个Prefix sum的并行版本,原本存在的loop dependency O(N),在并行版本下为O(logN)的loop,而每一个loop内部则是完全的并行计算(蓝色箭头示意部分)。

7.jpg

最后,还有一些计算量大,逻辑也很复杂的应用。比如GPU Ray Tracing就是一个很大,也很诱人的领域,can you feel it?

8.jpg

回到开头问题,当我们锄地时,你会选择两头牛呢,还是1024只鸡,希望这篇文章能帮助你找到自己的答案\~

作者:Peter6
原文链接:https://mp.weixin.qq.com/s/NyZib59ci9NluLcHwPM7uQ
微信公众号:
LET.jpg

更多IC设计技术干货请关注IC设计技术专栏。

推荐阅读
关注数
20187
内容数
1307
主要交流IC以及SoC设计流程相关的技术和知识
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息