CUDA学习笔记08: 深入理解CUDA的Warp

逻辑上,所有thread是并行的,但是,从硬件的角度来说,实际上并不是所有的thread能够在同一时刻执行,接下来我们将解释有关warp的一些本质。

warp是有硬件决定,目前一个warp内有32个thread,每一个thread交给一个core去执行,用一个block的warp是并行,乱序执行。

warp是SM的基本执行单元。一个warp包含32个并行thread,这32个thread执行于SMIT模式。也就是说所有thread执行同一条指令,并且每个thread会使用各自的data执行该指令。

block可以是一维二维或者三维的,但是,从硬件角度看,所有的thread都被组织成一维,每个thread都有个唯一的ID(ID的计算可以在之前的博文查看)。
每个block的warp数量可以由下面的公式计算获得:
这里写图片描述

一个warp中的线程必然在同一个block中,如果block所含线程数目不是warp大小的整数倍,那么多出的那些thread所在的warp中,会剩余一些inactive的thread,也就是说,即使凑不够warp整数倍的thread,硬件也会为warp凑足,只不过那些thread是inactive状态,需要注意的是,即使这部分thread是inactive的,也会消耗SM资源。

Warp Divergence
控制流语句普遍存在于各种编程语言中,GPU支持传统的,C-style,显式控制流结构,例如if…else,for,while等等。

CPU有复杂的硬件设计可以很好的做分支预测,即预测应用程序会走哪个path。如果预测正确,那么CPU只会有很小的消耗。和CPU对比来说,GPU就没那么复杂的分支预测了(CPU和GPU这方面的差异的原因不是我们关心的,了解就好,我们关心的是由这差异引起的问题)。

这样我们的问题就来了,因为所有同一个warp中的thread必须执行相同的指令,那么如果这些线程在遇到控制流语句时,如果进入不同的分支,那么同一时刻除了正在执行的分之外,其余分支都被阻塞了,十分影响性能。这类问题就是warp divergence。

CUDA学习笔记08: 深入理解CUDA的Warp_第1张图片

请注意,warp divergence问题只会发生在同一个warp中。

解决方法:
1. 通过查找表去掉分支
2. 通过计算去掉分支,例如:上述代码可以转换为:var = 3*(var+1+(var>0))

因此,我们在编程的时候要尽量是warp块完美对齐,也就是说一个warp里都满足条件或者都不满足条件,如果实在无法对齐,也就是说产生分支的时候,可以用上述的方法解决分支问题。

在数据量足够大的情况,分化现象很严重的时候对性能造成的影响是巨大的,至少30%,这个我做过实验验证过

参考链接: cuda warp

你可能感兴趣的:(CUDA)