1 OpenCL规范
OpenCL是第一个面向异构系统的通用编程架构。为了给开发者提供一个支持手机终端GPU开发的通用API,苹果公司在2008年的开发者大会上提出了OpenCL标准的草案,之后由非盈利性技术组织Khronos Group根据苹果公司的草案制定为异构计算标准,并一直由该工作组维护升级,目前OpenCL 2.0己于2013年正式发布。OpenCL异构计算标准从发布至今己取得了较大的成功,得到了业界众多企业的支持,包括苹果、AMD、英伟达、Altera、英特尔、IBM、赛灵思、ARM、德州仪器等众多知名企业。目前常见的异构计算平台包括GPU, FPGA, DSP (Digital Signal Processor)等。
OpenCL规范由四个部分组成,每个部分都有对应的模型进行描述,包括平台模型、执行模型、内存模型、编程模型。其中,平台模型是对异构系统硬件模型的高层抽象描述,它定义了异构系统由一个主机(Host)和一个(或多个)设备(Device )组成,主机用于协调整个系统,设备用于执行OpenCL C代码,被设备执行的OpenCL C代码又称为内核(Kernel )。执行模型定义了主机中的OpenCL环境是如何配置的,以及设各上的内核是如何执行的,具体包括:在主机端配置上下文、建立主机和设备通信的机制、定义设备端内核并行描述的机制。内存模型定义了内核使用的抽象分层存储模型,此模型虽然比较接近现代GPU的内存结构,但它与具体的硬件架构无关,对其他加速设备不存在任何限制。编程模型定义了内核并行执行模型与具体硬件结构的映射关系。
2 基于FPGA的OpenCL平台结构
OpenCL异构计算标准最大的优点在于它能支持所有的硬件加速平台,FPGA作为一种新型的异构计算加速平台,其推广和应用正处在起步阶段。FPGA主要组成部分为可编程输入输出单元(IOB,IO Bank)、可配置逻辑块(CLB, Configurable Logic Block)、时钟管理模块、嵌入式块RAM ( BRAM )、布线资源等如图2.11所示。传统的FPGA开发门槛较高,设计者不但需要掌握硬件电路的相关知识和FPGA底层硬件结构,还需要了解硬件描述语言等知识。而且传统的FPGA开发方法较为复杂,开发周期较长,尤其是高性能计算和大数据处理的相关应用,其FPGA的开发项目将非常复杂,往往需要耗费较多的人力资源。采用OpenCL标准进行FPGA的开发大大缩减了开发周期,降低了FPGA开发的门槛。
2.1 基于FPGA的OpenCL平台的设计流程
与传统工具的不同之处在于用户开发的程序并不是在固定架构处理器上运行的,AOC (Altera's OpenCL Compiler)可以将采用高级语言描述的OpenCL内核编译转化为在FPGA上运行的硬件逻辑电路。在处理能力及功耗等方面,有望获得与制作专用硬件时接近的性能。具体而言,可将按照OpenCL标准开发的程序中的加速器用程序(在OpenCL中称为“内核”程序)转换成FPGA上的逻辑电路,并将其作为FPGA的配置数据输出。运行时,主机端的程序会通过OpenCL用运行库,要求已被写入这些配置数据的FPGA进行内核处理。
该工具的最大优点是,程序员可在不具备硬件设计知识的情况下生成FPGA的配置数据。使用以前提供的开发工具,也能将以C语言编写的程序转换成FPGA上的逻辑电路。但是,要让逻辑电路完成数据处理工作,需要由CPU通过某些通信接口收发数据,而且为FPGA连接外部存储器的话,还必须设置存储器控制器等。因此,程序员需要具备可设计具备各种外围电路的系统LSI的知识。如图3-1所示,C语言自动生成FPGA硬件电路。其中主机程序利用OpenCL运行库API以及C/C++语言编写,内核程序使用由C语言扩展而来的“OpenCL C'’语言编写;在编译器生成的文件中,X86使用的二进制文件与SDK提供的OpenCL运行库一同运行,而FPGA的对象文件是用来配置FPGA,自动追加外部接口机内部互联电路的。
使用Altera OpenCL SDK的设计流程,可将根据OpenCL的规定编写的外部设备用内核程序转换成FPGA上的逻辑电路。Altera采用的方法是未降低FPGA本身所具备的灵活性,而是提高了方便性。
2.2 基于FPGA的OpenCL平台的访存机制
OpenCL内存模型与实际存储器体系结构无关,它定义了内核程序在设备上执行所用内存空间的抽象内存体系结构。OpenCL将内核程序中用到的内存分为了全局内存(global memory)、常量内存(constant memory)、本地内存(local memory)和私有内存(private memory)四种不同的类型。
各类内存的管理和使用如表2-1和2-2所示。
表2-1主机对内存空间的管理和使用 方式 全局 常量 本地 私有 Host 访问 可读写 可读写 不可访问 不可访问 (主机端) 分配 动态 动态 动态 不可分配 表2-2 kernel对内存空间的管理和使用 方式 全局 常量 本地 私有 Kernel 访问 可读写 只读 可读写 可读写 (主机端) 分配 不可分配 静态 静态 静态 这些不同的内存区域与平台模型的交互关系如图2-3所示。
FPGA的内存层次结构较少,与OpenCL标准的内存模型有较大的差异,如表2-1所示为 FPGA平台的与OpenCL规范内存模型的映射关系。
因为FPGA和主机在内存结构上是相互独立的,它们对自己的内存空间的操作一般是互不影响的,但是在很多情况下,主机和FPGA之间的内存空间需要交互。在OpenCL里有两种方式来实现此类交互:复制数据和内存映射。
复制数据是指主机通过相应的API函数将主机里的数据写入到OpenCL设备的内存中或者主机把OpenCL设备内存中的数据读出到主机内存中。这种交互方式是通过命令队列来实现的。
内存映射的方式允许将OpenCL设备内存对象通过相应的API函数映射到主机中的可见内存空间中。这样就可以直接在映射到主机端的内存空间实现对FPGA内存的读写。
基于FPGA的OpenCL入门教程
![](/skin/haowen/images/icon_star.png)
![](/skin/haowen/images/icon_star.png)
![](/skin/haowen/images/icon_star.png)
![](/skin/haowen/images/icon_star.png)