切割性能我读这篇文章:为什么一个“的if-else”语句(在GPU的代码)将在半
FPGA or GPU? - The evolution continues
而且有人发表了评论,他写道:
由于GPU是SIMD任何代码用“的if-else”语句将削减一半的 性能。一半核心将执行 语句的if部分,而一半核心处于空闲状态,然后另一半核心将执行其他计算,而核心的前一半 保持空闲状态。
我不明白为什么?
为什么使用GPU(即OpenCL)使用if-else
时性能会下降一半?
切割性能我读这篇文章:为什么一个“的if-else”语句(在GPU的代码)将在半
FPGA or GPU? - The evolution continues
而且有人发表了评论,他写道:
由于GPU是SIMD任何代码用“的if-else”语句将削减一半的 性能。一半核心将执行 语句的if部分,而一半核心处于空闲状态,然后另一半核心将执行其他计算,而核心的前一半 保持空闲状态。
我不明白为什么?
为什么使用GPU(即OpenCL)使用if-else
时性能会下降一半?
分行一般不会影响业绩,但分行分歧呢。也就是说,两条线程采用不同的路径(例如一个满足if
条件,另一个不满足)。由于GPU的所有线程都执行相同的“代码行”,因此某些线程必须等待,而不是其路径一部分的代码才会执行。
嗯,这是不是只在一个经编(NVIDIA)或波阵面(AMD)执行相同的“行代码”的所有线程真的。 (目前,NVIDIA GPU的扭曲大小为32,AMD GPU的海平面大小为64.)
因此,如果在内核中存在if-else
块,则最坏情况的性能确实会下降50%。甚至更糟糕:如果有可能的分支,则性能可以降低到没有分歧的性能的1/n
(即没有分支或者经线/波阵面中的所有线程都采用相同的路径)。当然,对于这种情况,您的整个内核必须嵌入在if-else
(或switch
)构造中。
但是,如上所述,只有在采用不同路径的线程处于相同的warp/wafefront中时才会发生这种情况。因此,编写代码/重新排列数据/选择算法/ ...可以尽可能避免分支分歧。
T1; DR:可以有分支,但是如果不同的线程采用不同的分支,它们必须位于不同的弯曲/水平面以避免发散并因此导致性能损失。
大多数时候,人们一读到分歧就会害怕GPU上的分支。但是,大多数时候内核在最高性能上运行得并不快,但由于内存带宽,共享内存或缺少可用的warp而限制了吞吐量。那么分歧对绩效影响很小。 –
@JanLucas:你是对的,几乎从未达到最佳表现,但分支分歧更糟糕。当然,对于可以在峰值性能附近运行的内核来说,性能的平分会导致更大的性能损失,但只能是绝对数量,而不是相对数量。我认为更好的理由不用担心分歧太多,通常情况下内核通常只在内核的一小部分内分裂成分支(例如,只有10%受分支影响,因此性能下降非常低) 。 – Shadow
@JanLucas:但它从来都不是坏的去想分歧,因为它往往齐头并进一个坏的数据布局,这导致未聚内存访问以及为此宝贵的内存带宽的浪费。 – Shadow
GPU的设计本质上不利于枝术,你应该考虑调整你的代码的这一特点。 – tibetty