基于OpenCL的CPU模块设计与实现
2018-05-14曾亚周琦章杰
曾亚 周琦 章杰
摘要:OpenCL作为异构系统下程序设计的主流架构之一,已经在大量异构计算系统中应用。由于异构系统最初的用途是用于在计算机系统中加速数值计算,设计人员在OpenCL框架下編写的模块大部分是用于数值计算,以及与数值计算息息相关的图像处理。本文介绍一种通过OpenCL搭建CPU模块的方法。CPU功能模块可在部分情况下分担或接管异构系统中部分CPU的工作。同时在一些支持可重构架构的异构系统中,CPU模块可以替代异构系统中的CPU,这大大增加了异构系统的灵活度。本文涉及的CPU模块兼容MIPS32指令集。
关键词:OpenCL;异构系统;CPU设计;MIPS
中图分类号:TP311 文献标识码:A 文章编号:1007-9416(2018)02-0160-02
近年来,随着单个CPU的各方面性能都达到了极限,只靠单个或者多个通用处理器(以下简称CPU)来提高计算机系统性能的解决方案已经不适用了。专用协处理器配合CPU的组合方式成了现在增强计算机系统性能的主要途径,“CPU+专用协处理器”构建的异构系统成了当前大规模数据处理的首选解决方案。不过,由于异构系统本身最初是用于解决计算机系统数值计算过慢的问题,也使得异构系统中几乎大部分模块都是直接用于数值计算,造成了异构系统在实际应用中也仅限于用在与数值计算息息相关的图像处理,信号处理,神经网络等方面。
OpenCL全称Open Computing Language,是指开放计算语言,用于编写在异构平台上执行的程序。作为现在流行的异构系统编程框架,可以让异构系统的应用可以不局限于数值计算中,也可用于非数值运算中。系统中协处理器不仅可以通过使用高级语言进行编程,而且OpenCL把协处理器与主处理器(大部分情况下由CPU担任)统一在一个框架下编程,这使得两者的数据交换变得非常简便与灵活。在某些状况下,协处理器可以承担主处理器的工作,分摊甚至接管主处理器的工作,主处理器只要把数据直接送入协处理器即可。这不仅拓宽了异构系统的使用范围,也减轻了主处理器的负担。特别是异构系统中如果支持协处理器可重构功能,那异构系统的使用范围可以大大增加。
本文通过OpenCL架构,设计一个在“CPU+GPU”的异构系统中能够运行的CPU模块。此模块兼容开源的MIPS32指令集,易于理解与掌握,方便设计人员应用。选择MIPS架构的理由是,MIPS架构源代码公开,相关资料丰富,易于理解与掌握。现在不少大学本科计算机专业课中,通过MIPS架构来讲解计算机系统原理架构,甚至部分大学的“微机原理与接口技术”课程中的用MIPS CPU代替老旧的8086CPU。
1 异构系统架构概述
1.1 OpenCL基本介绍
OpenCL(Open Computing Language,中文名为开放计算语言)是一个在异构系统中设计应用的框架,目的是方便在异构系统下编写程序的,此异构系统可通过CPU、GPU、DSP、FPGA或其他类型的处理器与硬件加速器所组成。(见图1)
OpenCL平台模型定义了使用OpenCL的一种高层模式,这个模型如图1所示。这平台包括一个宿主机(图1中的Host),设备就是执行指令流的地方。因此OpenCL的设备通常被称为计算设备(图1中的Compute Device),计算设备可以是GPU、FPGA等任何OpenCL架构下支持的任意处理器。
OpenCL的运行步骤比较复杂。基本上分为以下步骤:
(1)初始化阶段,获取设备信息,创建上下文(用于协调主机以及计算设备与主机的一种交互机制)。
(2)创建内存对象,然后创建程序对象,同时生成内核对象。内存对象存储内核执行数据,程序对象即程序源文件或者二进制代码数据。内核对象是设备程序的入口。
(3)配置内核参数,并配置工作数组的组织形式。同时将内核对象,以及工作数组参数放入命令队列中送入协处理器中执行。
(4)返回执行结果,并释放资源,程序结束。
1.2 CPU模块基本介绍
由于本文编写的是CPU模块,在这里需要简单讲解一下CPU的工作原理。
CPU的主要运作原理是执行储存在内存中里的一系列指令。CPU工作架构有冯·诺伊曼结构(von Neumann architecture)以及哈佛结构(Harvard architecture),由于MIPS架构属于冯·诺伊曼结构(von Neumann architecture)架构,因此本文只讨论冯·诺伊曼结构的运行方式。冯·诺伊曼CPU的运作原理可分为五个阶段:提取、解码、执行、访存和写回(见图2)。
提取:CPU自动地从存储器取出指令。为此,CPU能够知道取出指令的存储器地址,提取阶段中的存储器地址可以是生成,也可以是指令指定。
解码:CPU对从存储器取出的指令进行分析。指令分析有2个部分:1.指令中的操作命令,即需要CPU进行什么操作。2.指令中的操作数地址,即操作数的有效地址。
执行:从解码阶段中获取“操作命令”以及“操作数地址”后,形成控制型号,通过对CPU内各个部件的控制,完成指令操作。
访存:CPU会访问内存(或者高速缓存)访问内存读或者写数据。
写回:CPU把完成执行阶段的结果写入对应的存储器地址中。这一步是CPU执行的最后一个阶段。
2 CPU功能模块设计
通过上文的讲解,我们知道了OpenCL的结构以及CPU模块的运作原理。OpenCL最简单的工程通常有2类文件:.c以及.cl文件,.c文件运行于主处理器上,.cl文件运行于协处理器上。由于在本文的工程中,主CPU的功能就是用于输送CPU模块的二进制命令,所以CPU模块的编写集中于.cl文件中。
2.1 CPU模块整体概述
CPU模块的对外接口需要尽量与实际CPU保持一致,这样能够方便设计人员能快速熟悉模块使用。CPU模块对外接口主要分两块:指令与数据。它们各自有相同功能的输入输出接口变量。而这些输入输出接口为以下这些:
clk:时钟信号
rst:复位信号
int_i[6]:外部硬件中断输入
data_i[32]:输入数据
ack_i:输入响应
addr_o[32]:输出地址
data_o[32]:输出数据
we_o:输出使能信号
2.2 CPU模块内部功能实现
CPU模块内部依照CPU执行步骤进行区分,分为提取、解码、执行、访存和写回 这五个部分。
提取部分:主要功能是从对应指令地址取出指令。代码实现上,是通过把指令变量上获取的指令代码赋到内部变量中。同时把指令地址变量指向下一个地址。
解码部分:主要功能是解析指令,从指令中解析出操作类型,所需的源操作数,要写入的目的寄存器地址等。代码实现上,根据MIPS32指令集对指令代码进行分割,并把数值赋给对应内容的代码。
执行部分:主要功能是执行指令。代码实现上,通过一个巨大的switch来应对MIPS32的各自指令操作,;例如加减乘运算(MIPS支持乘法)、移位操作或者逻辑操作。
访存部分:主要功能是对一些需要执行存储器操作的。代码实现上,是把指令执行结果写到对外接口的变量中。
写回部分:主要功能是把相关指令操作的操作数写入寄存器。代码实现上,是把相关数值写入代表寄存器的内容。
3 仿真与功能实现
CPU模块在设计之时就需要考虑到模块验证。本文通过GNU环境下的MIPS交叉编译环境编译生成MIPS命令文件,本文生成的二进制文件是一个冒泡算法。通过程序实验证明,CPU模块能够正常解析程序命令,能够得出预期的实验结果。
4 结语
本文通过OpenCL架构编写在异构架构中能使用的CPU模块。此CPU模块支持完整的MIPS32指令集,并且在支持可重构的异构系统中,能够依照需求让协处理器能够实现CPU功能。在实际使用中拓宽了异构系统的使用范围,同时也丰富了设计人员在设计异构系统的模块库。由于当前很少有用于非数值运算的异构系统模块,不仅仅上CPU模块本身的功能拓展(比如把CPU模块中添加内存管理机制等),适合异构系统的非数值运算模块编写成了下一阶段的工作重点与方向。
参考文献
[1]薛勃,周玉洁.MIPS32 指令集兼容的CPU模拟器设计[J].计算机工程,2010,35(1):263-265.
[2]姚英彪,曾宪彬.嵌入式系统设计实验的QtMIPS仿真软件开发[J].实验室研究与探索,2017,36(1):99-103.
[3]叶继华,郭 帆,余 敏,马丽红,陶 玲.Intel X86 系列 CPU 模拟器的研究与实现 [J].江西师范大学学报(自然科学版). 2007. 31(6): 643-644.
[4]Dominic Sweetman. See MIPS Run[M]. San Francisco, California: Morgan Kaufmann,2006.
[5]范兴山,彭 军,黄乐天.基于OpenCL的FPGA 設计优化方法研究[J].电子技术应用,2014,40(1):16-19.
[6]Aaftab Munshi, Benedict R. Gaster, Timothy G. Mattson, James Fung, Dan Ginsburg. OpenCL Programming Guide [M]. Boston , Massachusetts. : Addison-Wesley, 2006.