OpenCL: A Parallel Programming Standard for Heterogeneous Computing Systems

摘要:介绍了近年来微处理器的关键架构和特征,描述了OpenCL提供的模型和抽象概念——OpenCL是针对这些架构的新的并行编程标准。

前言:OpenCL的产生(异构计算和并行架构的时代需求),解决的问题(支持异构计算,提供易于编程的API)和优势(可移植性、正确性)

OpenCL的编程模型:提供一种通用语言、编程接口、硬件抽象,用任务并行或数据并行计算加速应用程序(加速方式:任务并行或数据并行;编程接口:用于枚举的函数、上下文管理、内存设备管理、主从数据传输、OpenCL程序编译、内核函数及其他附属功能;支持离线或在线编译)。对指令集没有依赖,硬件的更新或改变不影响OpenCL的编译。

虽然OpenCL是范微处理器设计,但也要求匹配目标框架的编程习惯(底层硬件的性质可使一些编程策略比其他平台更合适)。

OpenCL编程模型以锁步方式执行指令。OpenCL定义了四种类型的内存系统:大型高延迟“全局”内存、小型低延迟只读 "常量 "内存、共享 "本地 "内存以及"私有 "内存或设备寄存器。本地存储器由全局存储器实现(高延迟),也可以使用片上SRAM或共享寄存器文件实现。

应用程序可查询设备属性,以确定可用计算单元和内存系统的属性,并相应地使用它们。应用程序启动前必须要先创建与设备对应的“上下文”,并将内存不足的设备排出在外(否则最大内存分配将受到能力最小的设备的限制)。

新创建的上下文在某些设备上不支持OpenCL运行时所需要的功能,这些设备就需要在上下文中移除。上下文创建后,OpenCL程序可以在运行时被编译,将源代码作为字符串数组传递给OpenCL编译函数。

OpenCL程序被编译后,可以获得该程序所包含的特定 "内核 "的句柄。然后,这些 "内核 "功能可以在OpenCL上下文中的设备上启动。OpenCL主机-设备内存I/O操作和内核是在目标设备上执行的,方法是将它们记入与目标设备相关的命令队列中。

OpenCL和现代处理器架构

1.多核CPU

由于它们通常用于对延迟敏感的工作负载,并具有最小的并行性,因此CPU广泛使用大型缓存来隐藏主内存的延迟。许多CPU还小规模地使用单指令多数据(SIMD)算术单元来提高密集算术和多媒体工作负载的性能。编写OpenCL内核时明确使用float4类型。

CPU的实现通常将所有的内存空间映射到相同的硬件缓存中,所以一个明确使用常量和局部内存空间的内核实际上可能比只使用全局内存引用的简单内核产生更多的开销。

2.The Cell Processor

CBEA(The Cell Broadband Engine Architecture)是一个异构的芯片架构,由一个64位电源兼容处理器元件(PPE)、多个协同处理器元件(SPE)、一个内存接口控制器和I/O单元组成,内部使用高速总线连接。

IBM的OpenCL实现支持Cell SPU的嵌入式配置文件,并使用软件技术来平滑Cell SPU和传统CPU之间的一些架构差异。在Cell处理器上,当操作数是16字节的倍数时,全局内存访问性能最好。使用较大的向量类型,如float16,使编译器能够展开循环,进一步提高性能。Cell DMA引擎使用双缓冲策略,结合调用async_workgroup_copy(),将数据从全局内存加载到本地存储。

3.GPU

GPU处理单元通常被组织在由单个指令解码器控制的SIMD集群中,共享对快速片上缓存和共享存储器的访问。与传统的CPU相比,使用SIMD架构和指令的无序执行使GPU能够在相同的面积上包含更多的算术单元。

最先进的GPU能够实现接近2 TFLOPS(每秒数万亿条指令)的单精度浮点算术率。由于图形工作负载的要求,GPU被设计为具有能够接近200GB/秒带宽的全局存储器系统。采用 "联合 "存储器访问时,性能达到峰值。否则将导致有效带宽大幅减少,并增加延迟。

虽然GPU本身是强大的计算设备,但其又必须由主机CPU管理。OpenCL为独立主机和GPU内存系统之间的CPU调度数据传输提供了API。最近的GPU能够通过PCI-e直接访问主机内存。零拷贝内存访问机制可作为OpenCL的下一个扩展或未来版本的一部分提供,实现数据在内核执行期间只读或写一次。

AMD和NVIDIA都发布了支持各自GPU的OpenCL实现。英伟达GPU对OpenCL所看到的各个PE使用标量处理器架构,使它们能够在大多数OpenCL数据类型上高效工作。AMD公司的GPU使用矢量架构,通常能达到最好的效率和性能,使OpenCL的工作项目在4元素的向量类型上运行。

在许多情况下,矢量化的OpenCL内核可以在X86 CPU和AMD及NVIDIA GPU上表现良好,尽管由此产生的内核代码可能比标量代码的可读性要差。

低级别的GPU架构的差异,包括哪些内存被缓存,哪些内存访问模式会产生库冲突,都会影响内核的优化。供应商提供的OpenCL文献通常包含低级别的优化指南。

4.OpenCL内核实例

以自适应泊松-波尔兹曼解算器(APBS)的内核说明了将串行代码转移到OpenCL的过程。当对网格点进行分解时,MDH方法本质上是数据并行的,因为它们是独立计算的,没有输出冲突。

OpenCL: A Parallel Programming Standard for Heterogeneous Computing Systems_第1张图片 MDH算法总结

实际上,OpenCL调度器成为网格点的外循环。OpenCL全局工作组的大小被设定为网格点的总数。由OpenCL调度的每个工作项都负责使用上述内核计算一个势。每个OpenCL工作项都获得其网格点的索引其全局工作项的索引。 

通过利用每个OpenCL计算单元上的快速片上 "本地 "内存,数据可以在本地内存中分阶段进行,然后有效地广播给同一工作组中的所有工作项。这极大地放大了算法可用的有效内存带宽,提高了性能。

片上共享内存被划分,因此工作组的每个工作项都在特定的偏移量上将位置、电荷和尺寸数据的一个块加载到共享内存。本地内存障碍被放置,以确保在一个工作组的所有工作项目访问数据之前,共享内存中的数据不会被覆盖。这种协调的数据加载和共享减少了缓慢的全局内存访问的数量。

5.总结

OpenCL将加入新的功能;

期望更多的增加支持线程安全;增加OpenGL的互操作性以及与CUDA等API中高级功能的扩展;

渴望OpenCL的实现能够包含更多的自动向量,使高效的内核能够以更少的向量宽度来编写;

作者认为OpenCL作为异构计算设备的标准低级并行编程接口具有很大的前景。

你可能感兴趣的:(硬件架构,人工智能,fpga开发,智能硬件)