(1) CUDA:可伸缩并行编程模型
CUDA是一种并行编程模型和软件环境,包含3个重要的抽象概念:线程组层次结构(warp、block、grid)共享存储器、屏蔽同步。
CUDA是Nvidia的GPGPU模型,在此架构下,一个程序分为两个部分:host端和device端。Host端是指在CPU上执行的部分,而device端则是在显示芯片上的部分。Device端的程序又称为“kernel”。通常host端程序会将数据准备好好,复制到显卡的内存中,再由显示芯片执行device端程序,完成后再由host端程序将结果从显卡的内存中取回。
由于CPU存取显卡内存时只能通过PCI Express接口,因此速度较慢(PCI Express X16的理论带宽是双向各4GB/s),因此不能太常进行这类动作,以免降低效率。
(2) 存储器层次结构
在Cuda架构下,显示芯片执行时的最小单位是thread,数个thread可以组成一个block,一个block中的thread能存取同一块共享的内存,而且可以快速进行同步的动作。
每一个block中所包含的thread数目是有限的(1-256),不过,执行相同程序的block,可以组成一个grid。不同block中的thread无法存取同一个共享的内存,因此无法直接胡同或进行同步。因此,不同block中的thread能合作的程度是比较低的。
Cuda线程可在执行过程中访问多个存储器空间的数据,每个线程都有一个私有的本地存储器。每个线程块都有一个共享存储器,该存储器对于块(block)内的所有线程都是可见的,并且与块具有相同的生命周期。最终,所有线程都可以访问相同的全局存储器。此外还有两个只读的存储器空间,可由所有线程访问,这两个空间是固定存储器空间和纹理存储器空间。
(3) GPU(Graphic Processing Unix):高度并行、多线程、多核处理器
GPU专为计算密集型、高度并行化的计算而设计,其设计能使更多晶体管用于数据处理,而非数据的缓存和流控制。更具体的说,GPU专用于解决可表示为数据并行计算的问题——在许多数据元素上并行执行的程序,具有极高的计算密度(数学运算与存储器运算的比率,数学运算量越高同时存储器运算量越少,计算密度越大);因而可以通过计算隐藏访问延迟(当第一个线程块运行完时,立 即运行第二个线程块)。
使用GPU还有几个好处:限时芯片通常具有更大的内存宽带,限时芯片具有更大量的执行单元。
有好处也就有不足:由于显示芯片的运算单元数量很多,因此对于不能高度并行化的工作,所能带来的帮助就不大;显示芯片目前通常只支持32bits的浮点数,且多半不能完全支持IEEE754规格,有些运算的精确度可能较低。目前许多显示芯片并没有分开的整数运算单元,因此整数运算的效率较差;显示芯片通常不具有分支预测等复杂的流程控制单元,因此对于具有较高高度分支的程序,效率会比较差。
总的说来,显示芯片的性质类似stream processor,适合一次进行大量相同的工作,CPU则比较有弹性,能同时进行变化比较多的工作。
(4) Cuda编程模型与Tesla架构的映射
Telsa架构的创建以一个可伸缩的多线程流处理器(SM)阵列为中心。当主机上的cuda程序调用内核网格时,网格的块将被枚举并分发到具有可用执行容量的多处理机上。一个线程块的线程在一个多处理机上并发执行,在线程块终止时,将在空闲多处理器上启动新快。
多处理器包含8个标量处理器(SP)为核心、两个用于先验的特殊函数单元、一个多线程指令单元以及芯片共享存储器。多处理器会在硬件中创建、管理和执行并发线程,而调度开销保持为0.
为了管理运行各种不同程序的数百个线程,多处理器利用了一种称为SIMT(单指令、多线程)的新架构。多处理器会将各种线程映射到一个标量处理器核心,各标量线程使自己的指令地址和寄存器状态独立执行。多处理器SIMT单元以32个并行线程为1组来创建、管理、调度和执行线程,这样的线程组称为warp块(32个并行线程)。构成SIMT warp块的各个线程在同一个程序地址一起启动,但也可以随意分支,独立执行。
为一个多处理器制订了一个或多个要执行的线程块时,它会将其分成warp块,并有SIMT单元进行调度,将块分割为warp块的方法总是相同的,每个warp块都包含了连续的线程,递增线程ID。