Cuda GPGPU:翘曲中有一台普通PC的结果

Cuda GPGPU:翘曲中有一台普通PC的结果,cuda,opencl,gpgpu,program-counter,Cuda,Opencl,Gpgpu,Program Counter,我在一本书中读到,在波前或扭曲中,所有线程共享一个公共程序计数器。那么它的后果是什么呢?这有什么关系 这意味着所有线程同时运行相同的命令。这对于确保所有线程在处理当前行时都已完成前一行非常重要。例如,如果需要将数据从一个线程传递到另一个线程,则需要确保数据已经由第一个线程写入。因为程序计数器是共享的,所以您知道,一旦写入数据行完成,数据就存在于所有线程中。NVIDIA GPU一次执行32个线程(扭曲),AMD GPU一次执行64个线程(波前)。控制逻辑、提取和数据路径的共享减少了面积,提高了性能

我在一本书中读到,在波前或扭曲中,所有线程共享一个公共程序计数器。那么它的后果是什么呢?这有什么关系

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

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


为了利用设计编程语言和开发人员需要了解如何合并内存访问以及如何管理控制流分歧。如果扭曲/波前中的每个线程采用不同的执行路径,或者如果每个线程访问的内存明显不同,则设计的好处将丢失,性能将显著降低。

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

那么gpu制造商为什么要这么做呢?由于缺少单独的程序计数器、分支预测和大型缓存,芯片中的算术逻辑单元(ALU)可以节省大量硅。更多的ALU意味着更多的工作组或并发线程


相关:

与往常一样,了解发动机罩下的工作原理有助于提高性能。从OCL开发者的角度来看,我们只知道

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

在谈到分支时,这一点以及SIMT体系结构目前的工作方式导致了这种考虑(从这里):

仅当条件不一致时,才执行两个分支 在本地工作组中的线程之间,这意味着如果 在本地工作表中的工作项之间计算为不同的值 组,当前一代GPU将执行两个分支,但仅 正确的分支将写入值并产生副作用

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

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

这是:

if (threadIdx.x / WARP_SIZE > 2) {...} else {...}
在第一种情况下,第一个经纱内会出现发散(NVIDIA为32条经纱)。但不是在第二种情况下,不管工作组的大小如何,它总是扭曲大小的倍数。显然,这两个例子做的不是同一件事。但在某些情况下,您可能能够重新排列数据(或找到另一个技巧),以保持第二个示例的原理


这似乎与现实相去甚远,但现实生活中的一个例子是减少。通过在“SIMD友好结构”中订购您的操作,您可以在每个阶段消除一些扭曲(因此为其他工作组中的一些扭曲留出空间)。有关完整的解释和代码,请参阅本节的“利用可交换性”一节。

Warp同步编程是一种特定于实现的优化。开发人员可以通过利用warp同步编程实现显著的收益。然而,大多数GPGPU计算语言并没有很好地定义warp同步编程,并且鼓励开发人员使用所有必需的线程围栏和屏障,就好像所有线程都是独立执行的一样。有人能提供一个参考来证明“波阵面/warp有一个公共的程序计数器”这一说法吗?本书提出了相反的观点每个GPU线程都有自己的标量寄存器、线程专用内存、线程执行状态、线程ID、独立执行和分支路径以及有效的程序计数器,并且可以独立寻址内存。虽然当线程的PC相同时,一组线程(例如32个线程的扭曲)执行效率更高,但这并不是必需的。”(请参阅)我自己找到了一个解决方案。重要的是“有效”一词“在上面的引文中。事实上,每个扭曲/波前只有一个程序计数器,因为硬件被组织为SIMD,在那里,您只能为所有SIMD通道发出一条指令(禁用控制路径发散的通道,并在下一个时钟周期中执行这些通道)。然而,从逻辑上看,似乎每个CUDA线程/OpenCL工作项有1台PC。这就是为什么SIMT在SIMD硬件上有时被称为SPMD。(计算机体系结构:定量方法和应用)
if (threadIdx.x / WARP_SIZE > 2) {...} else {...}