CA10 数据级并行性

图形处理单元

  • GPU和CPU没有共同的祖先
    • GPU前身是图形加速器,做好图形处理是其存在的原因
    • GPU在走向主流计算的同时,仍然不能放弃自己在图形处理上的责任
  • GPU与矢量处理器和SIMD体系结构不同!

要点

  • 异构计算模式需要协作良好的计算调度:CPU是主机,GPU是设备
  • 编程环境具备多种类型的并行性:多线程、MIMD、SIMD和指令级
  • GPU专用的类C编程语言——CUDA
  • 将所有类型的并行性统一为CUDA线程
  • 编程模型为单指令多线程

GPU 编程

线程块 Thread Block 被限制在一起执行的线程

网格 Grid 线程块的集合

多线程SIMD处理器:执行全部线程块的硬件

技术术语

  • dimGrid 网格维度
  • dimBlock 线程块维度
  • blockIdx 线程块索引
  • threadIdx 线程索引
  • blockDim 线程块的大小

GPU中的并行执行和线程管理由硬件处理,而不是由应用程序或者操作系统来完成。

CUDA

要求线程块能够以任何顺序独立执行,且不同线程块之间不能直接通信,而是通过全局存储器交换数据

关注性能需要牢记CUDA的硬件结构

对于CUDA,编程效率和性能之间的折中方案是让程序员能够通过代码来控制硬件

英伟达GPU计算结构和矢量体系结构的对比

相似点

  • 很好的处理数据级并行性问题
  • 搜集-分散数据传输
  • 掩码寄存器
  • 更大的寄存器文件

不同点

  • 没有标量处理器
  • 使用多线程来隐藏存储器延迟
  • 具有许多功能单元,而不是深度流水单元

英伟达GPU 计算结构

网格:运行在GPU上的代码,由一组线程块组成

  • 网格-矢量化循环
  • 线程块-循环体

线程块通过线程块调度器分配给执行该代码的多线程SIMD处理器

线程块

多线程SIMD处理器

SIMD通道:SIMD处理器并行功能单元

  • 与矢量体系结构中的矢量通道相似

32-bit宽的SIMD指令组成SIMD线程或warp

  • 映射到16个物理通道
  • 每条SIMD指令需要两个时钟周期

每个SIMD处理器上最多调度32个warp

  • 每个warp拥有自己的PC
  • 线程调度程序使用计分板来调度warp中准备好运行的SIMD指令
  • warp之间不存在数据相关
  • 将warp调度到流水线中

寄存器

  • 包含32-64k个32bit寄存器

多线程SIMD处理器的两级硬件调度器

线程块调度器:将线程块非陪给多线程SIMD处理器

SIMD线程调度器:在多线程SIMD处理器内,调度SIMD指令线程执行

  • 假设存在足够多的SIMD指令线程来隐藏DRAM延迟和提高多线程SIMD处理器的利用率

条件分支

与矢量体系结构,GPU分支硬件也是用内部掩码

  • 分支同步堆栈:内容由每个SIMD通道掩码组成

GPU的存储器结构

每个SIMD通道都有片外DRAM私有部分

  • 私有存储器
  • 用途:堆栈帧、溢出存储器和不适合放在寄存器中的私有变量
  • SIMD通道不共享私有存储器
  • GPU在L1和L2缓存器中缓存这个私有存储器

每个多线程SIMD处理器也有局部存储器

  • 低延迟、高带宽、小型暂存存储器——48KiB
  • 由块内的SIMD通道/线程共享
  • 创建线程块时动态申请,线程块退出时释放

由SIMD处理器共享的存储器是GPU存储器

  • 主机可以读写GPU存储器

GPU与矢量体系结构的对应

SIMD处理器类似于矢量处理器,GPU中多个SIMD处理器作为独立的MIMD核

最大不同:多线程是GPU的基础,绝大多数矢量处理器没有。

CPU与SIMD体系结构

GPU有多个SIMD通道

GPU硬件支持更多的线程

二者的双精度和单精度的性能之比2:1

二者都是64位地址,但GPU有更小的存储器

循环级并行性

循环承载相关性:循环不同迭代之间的数据相关性

循环承载相关性通常是重现的:如a[i]=a[i]+a[i-1],发生在使用先前迭代中该变量的取值定义该变量时

发现相关性

相关性分析复杂性来源于编程语言中的数组和指针的引用

  • 因为标量变量访问时使用名称的

所有相关性分析算法均基于数组索引是仿射前提

  • a*i+b

一般情况下,编译时很难确定相关性

稀疏矩阵访问时非仿射访问

m<=a<=n, m<=b<=n

最大公约数测试:如果存在循环承载相关性,则GCD(c,a)mod(d-b)=0