xucvai · 2020年07月07日

从现代GPU编程角度看SIMD与SIMT

作者:Keepin
转自:知乎

从字面定义看SIMD是指同一条指令多个数据。SIMT是同一条指令多个线程。他们共同的一个点就是同一条指令。

最近了解了下Amd,Arm,Nvidia三家公司提供的GPU。最早看到SIMT应该是在Nvidia上,通过对这三家公司的GPU架构进行研究,最后得出这样一个结论,近5年这三家公司的GPU都是基于SIMT架构的。

SIMT和SIMD到底有什么区别。在Nvidia的一些文档上得出的结论是非常小,其实我蛮同意这一个观点的。

1、从一个线程角度看。从我的研究看,SIMD一般是这样实现的,一个线程处理一条指令,这条指令是向量化处理的。例如一个32bit位宽的4维向量vec4,一条指令最快就在一个cycle执行完。那SIMT,最快要用4个cycles来完成。在SIMT的架构上,会把vec4分解开,然后一个cycle处理完一个数据。所以最快需要4个cycle。好了这里我们讲的是一个线程的情况看,但从这个角度,大家可能都觉得SIMD效率更高。

2、单个线程的SIMD核SIMT逻辑单元对比。从上述中看,基本可以认为单个线程看,SIMD相对SIMT需要4倍的逻辑单元。这里的逻辑单元可以认为是最基本的逻辑计算单元。当然也可以理解为单个线程的面积SIMD基本接近SIMT的4倍面积。

3、单核同时多线程。GPU之所以能够用于加速,最重要的一个点就是在gpu内部,一个核(core)可以同时并行很多线程。例如AMD的gpu,有一些core能同时运行64-256个线程。

4、单核同时多线程SIMD和SIMT同等算力对比。很显然SIMD的线程个数是SIMT线程的n分之一就可能实现同等算力。为了达到这种情况,算法的实现必须严格的按照n维的整数倍来实现。例如对于4维的SIMD实现,如果是用的vec3的情况,不难发现,SIMD架构浪费了一个计算单元。或许可以通过编程把这个计算单元用回来,但是很明显很麻烦,要求很高。所以SIMD对开发人员或者编译器的要求极高,才能真正达到算力不浪费。

5、SIMD在线程越来越多的时候不在有优势。很显然,随着线程越来越多,SIMD如果单纯把向量维度增加的话,会出现vec16。对于这么长维度的话,浪费可能越来越多。因此有些架构可能会对16个线程分成4组的SIMD。然后线程打包成4组一个包。

6、SIMT在多线程的不足。因为SIMT始终是同一条指令的,从寄存器角度看就是PC指针始终是一样的。如果线程太多的时候,有些线程需要分支跳转(if-else),那么效率就会降低,所以很多GPU对分支计算一般耗时是多个分支的总和。

综合上面几个描述看,SIMD和SIMT从某个层级上看,他们一个cycle都是执行同一条指令的,SIMD通常同时获取连续的一个向量长度数据,而SIMT则通常获取一个数据进行处理,如果想对IO访问更高效,需要开发者对线程的执行进行更精心的布局。总而言之,SIMT相对于SIMD确实在复杂计算的情况下,对开发人员和编译器的要求更低,更好优化。

然而,SIMD跟SIMT就完全互斥了,也不尽然。从上述的描述看,SIMT最终还是一个线程的处理,那如果单个线程就支持SIMD是不是也是可以的。完全可以。但是有没有必要呢?有必要。因为第1点中,如果注意看到了32bit这个关键词,那么你应该想到了。有些运算是16bit甚至是8bit的,是不是可以通过在SIMT中增加SIMD来增加GPU的计算能力。这就是为什么有些GPU的16位/8位计算的算力会是32位计算的多倍的情况。当然具体的实现以及需要增加多少成本都需要GPU IP核厂商深入评估了与及对GPU应用场景的设定。

最后,给开发者也提个醒,SIMT架构毕竟更类似标量运算,因此,很多GPU会引入合并访问技术。就是说单核多个线程如果连续的访问一片内存,可能效率更高,特别是针对I/O密集型的算法。



推荐阅读

推荐阅读
关注数
3
内容数
4
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息