GPGPU:在变形中使用普通PC的后果

时间:2014-08-24 16:03:04

标签: cuda opencl gpgpu program-counter

我在一本书中读到,在wavefront或warp中,所有线程共享一个共同的程序计数器。那么它的后果是什么呢?为什么这么重要?

4 个答案:

答案 0 :(得分:2)

NVIDIA GPU一次执行32个线程(warp),AMD GPU一次执行64个线程(波前)。控制逻辑,提取和数据路径的共享减少了面积并增加了性能/面积和性能/瓦特。

为了利用设计编程语言,开发人员需要了解如何合并内存访问以及如何管理控制流分歧。如果warp / wavefront中的每个线程采用不同的执行路径,或者如果每个线程访问显着不同的内存,那么设计的好处就会丢失,性能会显着下降。

答案 1 :(得分:1)

这意味着所有线程同时运行相同的命令。这对于确保在处理当前行时所有线程都已完成前一行非常重要。例如,如果您需要将数据从一个线程传递到另一个线程,则需要确保数据已由第一个线程写入。因为程序计数器是共享的,所以一旦写入数据行完成,数据就存在于所有线程中。

答案 2 :(得分:1)

正如其他一些答案所述,线程(warps / wavefronts)在每个工作组的基础上彼此同步执行。对于开发人员而言,这意味着您需要特别注意任何分支/条件逻辑,因为如果组中至少有一个工作项击中了“其他”分支/条件逻辑。条件,执行该代码时所有其他工作项暂停。

那么为什么gpu制造商想要这样做呢?缺少单独的程序计数器,分支预测和大型高速缓冲存储器为芯片中的更多算术逻辑单元(ALU)节省了大量的硅。更多ALU等于更多工作组或并发线程。

相关:CPU vs GPU hardware.

答案 3 :(得分:1)

像往常一样,了解工作情况下的工作方式可以帮助您提高性能。从OCL开发人员的角度来看,我们只知道

  

给定工作组中的工作项同时执行   处理单个计算单元的元素。 (OCL规范1.2 - 第3.2节)。

当谈到分支时,这和SIMT架构的工作方式现在会引起这种考虑(来自post):

  

仅当条件不一致时才执行两个分支   在本地工作组中的线程之间,这意味着条件   评估本地工作中的工作项之间的不同值   组,当前一代GPU将执行两个分支,但仅限   正确的分支会写出值并产生副作用。

这是非常正确的但并没有给你任何关于如何避免分歧的内部(请注意,这里我们仍处于工作组级别)。

但是要知道工作组由一个或多个warp组成,其中工作项共享PC(而不是工作组级别)有时可以帮助您避免分歧。只有当一些工作项在一个warp 中采用不同的路径时你才会有分歧(两个分支都被执行)。 考虑这个(source):

if (threadIdx.x > 2) {...} else {...}

和此:

if (threadIdx.x / WARP_SIZE > 2) {...} else {...}

在第一种情况下,第一次warp(NVIDIA的32个线程)内会有分歧。但不是在第二种情况下,无论工作组的大小如何,它都将是经线大小的倍数。显然,这两个例子并没有做同样的事情。但在某些情况下,您可能能够重新排列数据(或找到另一个技巧)以保持第二个示例的哲学。

这似乎远离现实,但现实生活的例子是减少。通过在“SIMD友好结构”中订购您的操作,您可以在每个阶段放弃一些经线(因此为其他工作组的其他人留出空间)。请参阅此whitepaper中的“利用交换性”部分获取完整说明和代码。