购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

5.1 沐曦GPU并行架构

正如图3-2所示,沐曦GPU的并行架构是围绕一个AP的可扩展运算单元(Processing Element Unit,PEU)来构建的,通过复制这种架构的构件来实现硬件并行。每个GPU设备通常有多个AP,每个AP都能支持上千个GPU线程的并行执行。当启动一个核函数网格时,它的GPU线程会被分配到可用的AP上执行。一旦线程块被调度到一个AP上,其中的线程将只在该指定的AP上并行执行。根据AP资源的可用性对多个线程块进行调度,这些线程块可能会被分配到同一个AP或不同的AP上。同一线程中的指令利用指令级并行性进行流水化。

MXMACA编程采用单指令多线程(SIMT)架构来管理和执行线程。每64个线程为一组,这被称为线程束(Wave)。线程束中所有的线程同时执行相同的指令,每个线程都有自己的指令地址计数器和寄存器状态,并利用自身数据执行当前的指令。每个AP都将分配给它的线程划分到线程束中,然后在可用的硬件资源上调度执行。64个线程组成一个线程束,这和OpenCL的线程束大小是一致的(waveSize=64)。MXMACA软件的程序设计需要参照waveSize来定义线程块的大小、优化工作负载,以适应线程束的边界,这能更有效地利用GPU资源。

SIMT架构与SIMD架构相似,两者都将相同的指令广播给多个执行单元来实现并行。一个关键的区别是,SIMD要求同一向量的所有元素在一个同步组中一起执行,而SIMT则允许同一线程束的多个线程独立执行。尽管一个线程束中所有的线程在相同的程序地址同时开始执行,但单独的线程仍可能有不同的行为。SIMT使程序员能够为独立的标量线程编写线程级并行代码,以及为协调线程编写数据并行代码。SIMT包含以下3个SIMD所不具备的关键特征:每个线程都有自己的指令地址计数器;每个线程都有自己的寄存器状态;每个线程都可以有一个独立的执行路径。

一个线程块只能在一个AP上被调度,一旦线程块被调度,其就会被保存在该AP上直到执行完成。在AP中,本地共享内存和寄存器是非常重要的资源。本地共享内存被分配在AP的常驻线程块中,寄存器在线程中被分配。线程块中的线程通过这些资源可以进行合作和通信。尽管线程块里的所有线程在逻辑上都可以并行运行,但在物理层面并非都能同时执行,因此,线程块里的线程可能会以不同的速度前进。

GPU编程的执行模型如图5-2所示。

图5-2 GPU编程的执行模型

GPU硬件将执行核函数的各个实例定义为一个工作项(Work-item),其等同于MXMACA程序里的一个GPU线程(Thread)。工作项由它在索引空间中的坐标来标识,这些坐标就是工作项的全局ID。

GPU硬件会为提交给相同的核函数执行的命令创建一个相应的工作项集合,称之为工作组(Work-group),其等同于MXMACA程序里的一个线程块(Thread Block)。工作组中的各个工作项使用核函数定义的同样的指令序列。尽管指令序列是相同的,但由于代码中的分支语句或者通过全局ID选择的数据可能不同,因此,各个工作项的行为也可能不同。

工作组提供了对索引空间粒度更粗的分解,其跨越整个全局索引空间。工作组在同一维度的大小相同,这个大小可以整除各维度中的全局大小。可以为工作组指定一个唯一的ID,这个ID与工作项使用的索引空间有相同的维度。可以为工作项指定一个局部ID,这个局部ID在工作组中是唯一的。这样就能由其全局ID或者由其局部ID和工作组ID唯一地标识一个工作项。

一个软件线程网格是一个 N 维网格(一维、二维或三维网络),也被称为线程网格。一个软件线程网格包括多个工作组,每个工作组负责执行线程网格指定的一个工作项集合。

给定工作组中的工作项(GPU Thread)会在一个计算单元的处理单元上并行执行,这是理解MXMACA编程完成多任务并发工作的关键。在用GPU编程实现具体的计算任务时,可能需要串行化核函数的执行,甚至可能需要在核函数调用中串行化工作组的执行。MXMACA编程只能确保一个工作组中的工作项并行执行且共享设备上的处理器资源。不要认为工作组或核函数调用会并行执行,尽管实际上它们通常确实会并行执行,但是算法设计人员不能依赖这一点。

在并行线程中共享数据会引起竞争:多个线程以不确定的顺序访问同一数据,这会导致不可预测的程序行为。MXMACA编程提供了一种方法来同步线程块里的线程,以保证所有的线程在下一步行动之前都到达执行过程中的一个特定点,但没有提供线程块之间同步的原语。

尽管线程块里的线程束可按任意顺序调度,但活跃线程束的数量还是会受AP资源限制的。当线程束因任意原因闲置时,AP可以从同一AP上的常驻线程块中调度其他可用线程束。在并行执行的线程束间切换没有开销,因为硬件资源已经被分配到了AP上的所有线程和线程块中,所以最新被调度的线程束的状态已经被存储在AP上。

AP是沐曦GPU架构的核心,寄存器和共享内存是AP中的稀缺资源。MXMACA将这些资源分配到AP中所有的常驻线程里,因此,这些有限的资源限制了在AP上活跃的线程束数量,活跃的线程束数量可以作为衡量AP上并行量的一个指标。了解一些AP硬件组成的基本知识有助于组织线程和配置核函数执行以获得最佳的性能。下面以沐曦MXC系列GPU(曦云)架构为例进行介绍。

5.1.1 设备线程架构信息查询

MXMACA线程架构相关的设备属性见表5-1。

表5-1 MXMACA线程架构相关的设备属性

以曦云架构GPU为例,设备线程架构信息查询代码见示例代码5-1。

示例代码5-1 设备线程架构信息查询代码

设备线程架构信息查询结果如图5-3所示。

图5-3 设备线程架构信息查询结果

5.1.2 核函数的并发执行和串并行执行

我们在第1.4.5节中总结过,GPU主要被用于解决计算密集型问题或数据并行处理问题,其特点是可以多任务并发。这些任务在业务逻辑上是并发的,它们既可以被无序串行执行也可以被同时并行执行,且不论哪种执行方式都不影响最终的执行结果。我们称这些任务具有并发性,其业务特点如图5-4所示。

图5-4 多任务并发

GPU多任务并发问题的求解过程,通常是通过在GPU上执行多个核函数来实现的。多个并发性核函数在GPU上如何执行呢?这取决于GPU程序员如何设计和开发程序,相应地GPU资源的利用率及程序性能也会大不相同,如图5-5所示。从程序员的角度看,并发核函数的并行执行使得GPU表现得更像MIMD架构。

图5-5 GPU核函数的串行执行和并行执行

曦云架构GPU在主机与GPU之间提供了16个硬件工作队列,保证了GPU上并发核函数可以更多地实现并行执行,更大限度地提高了GPU资源的利用率。

5.1.3 核函数的启动方式

曦云架构GPU既支持在CPU上启动核函数,也允许GPU在执行核函数时动态地启动新的核函数。在GPU编程术语中,后者一般被称为动态并行功能,即任一核函数都能启动其他的核函数,并管理任何核函数之间需要的依赖关系。图5-6展示了没有动态并行功能时主机在GPU上启动每个核函数的方式,以及有动态并行功能时GPU启动嵌套核函数的方式。通过GPU动态并行启动核函数有以下这些优势:首先,大幅减少了核函数从CPU启动的次数,减少了CPU与GPU的通信需求;其次,核函数的并发性得到了增强,例如,图5-6左边子图第三行的两个并发任务和第四行的三个并发任务是串行执行的,这些任务在右边子图演变成了五个可以并行执行的并发任务。

图5-6 支持GPU动态启动嵌套核函数功能的优势 7qTmU9kXfonWt5t4eENsLC7TsOZ5MtiLqIsWp2yDkKbzaGY/AXc2xBBz80J0Cpzr

点击中间区域
呼出菜单
上一章
目录
下一章
×