基于FPGA的并行计算技术
1 微处理器与FPGA
微处理器普遍采用冯·诺依曼结构,即存储程序型计算机结构,主要包括存储器和运算器2个子系统。其从存储器读取数据和指令到运算器,运算结果储存到存储器,然后进行下一次读取-运算-储存的操作过程。通过开发专门的数据和指令组合,即控制程序,微处理器就可以完成各种计算任务。冯·诺依曼型计算机成功地把信息处理系统分成了硬件设备和软件程序两部分,使得众多信息处理问题都可以在通用的硬件平台上处理,只需要开发具体的应用软件,从而极大地降低了开发信息处理系统的复杂性。然而,冯·诺依曼型计算机也有不足之处,由于数据和指令必须在存储器和运算器之间传输才能完成运算,使得计算速度受到存储器和运算器之间信息传输速度的限制,形成所谓的冯·诺依曼瓶颈[1];同时,由于运算任务被分解成一系列依次执行的读取-运算-储存过程,所以运算过程在本质上是串行的,使并行计算模式在冯·诺依曼型计算机上的应用受到限制。
受到半导体物理过程的限制,微处理器运算速度的提高已经趋于缓慢,基于多核处理器或者集群计算机的并行计算技术已经逐渐成为提高计算机运算性能的主要手段。并行计算设备中包含多个微处理器,可以同时对多组数据进行处理,从而提高系统的数据处理能力。基于集群计算机的超级计算机已经成为解决大型科学和工程问题的有利工具。然而,由于并行计算设备中的微处理器同样受冯·诺依曼瓶颈的制约,所以在处理一些数据密集型,如图像分析等问题时,计算速度和性价比不理想。
现场可编程门阵列(FPGA)是一种新型的数字电路。传统的数字电路芯片都具有固定的电路和功能,而FPGA可以直接下载用户现场设计的数字电路。FPGA技术颠覆了数字电路传统的设计-流片-封装的工艺过程,直接在成品PFGA芯片上开发新的数字电路,极大地扩大了专用数字电路的用户范围和应用领域。自从20世纪80年代出现以来,FPGA技术迅速发展,FPGA芯片的晶体管数量从最初的数万个迅速发展到现在的数十亿个晶体管[2],FPGA的应用范围也从简单的逻辑控制电路发展成为重要的高性能计算平台。
FPGA芯片中的每个逻辑门在每个时钟周期都同时进行着某种逻辑运算,因此FPGA本质上是一个超大规模的并行计算设备,非常适合用于开发并行计算应用。目前,FPGA已被成功地应用到分子动力学、基因组测序、神经网路、人工大脑、图像处理、机器博弈等领域,取得了数十到数千倍的速度提高和优异的性价比[3-18]。
2 FPGA并行算法的设计与开发
FPGA通过逻辑电路实现计算功能,而微处理器则通过程序和存储器控制计算过程。FPGA和微处理器在基本架构上的根本区别,决定了它们算法的设计理念和方法也存在很大区别[4-5]。与微处理器相比,FPGA最主要的优势是可以同时对大量变量进行逻辑运算和赋值,实现并行运算;而FPGA最主要的劣势则是失去了微处理器所提供的许多基本计算工具,如浮点数计算、初等函数取值等。在设计FPGA算法时,应该充分发挥FPGA可以同时对大量变量进行逻辑运算和赋值的优势,而尽量避免使用浮点数运算、初等函数取值等数值计算功能,所以并不是任何并行计算问题都适于在FPGA上实现。一般来说,FPGA最适用于需要大量并行逻辑或者整数运算的计算任务。例如,图像处理应用中的线性除噪、形态学变换、边缘检测、模式匹配等应用,就非常适合在FPGA上实现[10-16]。
FPGA算法中常用的电路结构包括流水线型和并行阵列型两种(见图1)。在流水线型结构中,计算任务被分解成多个子任务,由多个子电路依次完成,多组数据依次进入流水线电路,同时进行不同阶段的计算(见图1(a))。忽略首批数据进入流水线的延迟,流水线型电路处理数据的用时等于所有子任务中最长的用时。如果每个子任务都可以采用组合电路来完成而不需要时序电路,则所有子任务都可以在一个FGPA时钟内完成,从而实现极高的运算速度和性价比。
图 1 流水线型电路和并行阵列型电路
在并行阵列型电路中,多组并行排列的子电路同时接收整体数据的多个部分进行并行计算(见图1(b))。并行阵列型电路中的子电路本身可以是简单的组合电路,也可以是复杂的时序电路,如流水线型电路。如果受逻辑资源限制,无法同时处理全部数据,也可以依次处理部分数据,直到完成全部数据的处理。
图2示出了FPGA系统的开发流程。一般采用硬件描述语言(HDL),如Verilog、VHDL等,实现FPGA并行算法。虽然有一些类似C语言的软件可以帮助没有数字电路设计经验的用户实现FPGA设计,但是由于包括C语言在内的微处理器编程语言蕴含了许多微处理器的计算模式和理念,所以会影响或干扰FPGA并行算法的实现。使用HDL可以更好地结合FPGA的计算模式,设计出更合理的并行算法。一般选用FPGA开发板作为FPGA开发和测试的平台。开发过程中所需要完成的功能仿真、设置管脚、编译综合等步骤需要依托FPGA供应商提供的编译和通信测试软件。
下面以二值形态学腐蚀变换为例,设计一个简单的并行FPGA算法。如果把一幅二值图像中所有前景像素的集合称为A,把某个内核集合称为B;把该内核中心在x图像点时所包含的前景像素的集合称为B(x),则以B为结构元素的腐蚀变换定义为集合{X|B(x)A}。具体的计算任务是以包含右相邻和下相邻像素的内核为结构元素,对多幅6×6的二值图像进行连续两次腐蚀变换。采用Verilog语言,设计了一个三级流水线电路(见图3和图4)来实现这个计算任务。这个电路处理一幅图像的平均时间是一个FPGA时钟。在逻辑资源允许的情况下,相同的算法可以处理任何尺寸的图像,而且处理时间保持为一个FPGA时钟。
腐蚀变换电路的Verilog源程序如下:
3 FPGA在机器博弈方面的应用
机器博弈是智能科学技术的一个重要研究领域。搜索博弈树是机器博弈的基本方法。由于博弈树的状态空间巨大,因此提高搜索速度一直是机器博弈领域的重要研究课题。采用专用数字电路可以显著提高搜索速度。曾经击败国际象棋世界冠军的机器博弈系统Deep Blue就是采用了专用数字电路来提高树搜索的速度[19]。FPGA提供了实现树搜索专用数字电路的更便捷的方法。目前已经有人尝试采用FPGA提高中国象棋和9路围棋的搜索速度[17-18]。下面介绍的基于FPGA的9路围棋博弈系统中吃子算法的设计,展示了FPGA算法设计的特点和方法。
围棋规则规定,棋盘上的每个棋子本身或者与其相连的棋子必须至少与一个空位相邻(至少有一口气),不符合这个规则的棋子必须被拿掉(吃子)。实现这一规则的串行算法是依次在某个棋子本身的4连通点,或者与其相连同色棋子的4连通点搜索空位。有两个原因使这个串行算法不适于在FPGA上应用。首先,由于算法是串行的,因此无法在流水线型电路上实现,影响计算速度;其次,由于算法需要可寻址的储存空间,无法在FPGA上直接实现。
设计以下并行算法来实现吃子规则(见图4),即不断地去除与空位直接相连的同色棋子(相当于腐蚀形态学变换),最后剩下的棋子就是需要拿掉的棋子。把这些棋子从棋盘中去掉就完成了吃子规则。这个算法可以通过一个19级流水线电路实现,处理一个棋盘的平均时间只要一个FPGA时钟。为了实现流水线型电路,图4中对棋盘的复制是必需的步骤。这个示例说明了在FPGA上实现并行计算不能简单翻译微处理器上的原有算法,而是要根据FPGA和计算问题的具体特点,从新设计相应的并行算法。
图 4 吃子算法
基于相似的并行算法,用一个167级的流水线实现了模拟黑白双方各走一步的功能,并在此基础上实现了对整盘围棋的蒙特卡罗模拟,比基于微处理器的蒙特卡罗模拟快了170倍[18]。
4 结束语
本文介绍FPGA并行计算技术的基本特点和方法。选择适当的计算问题,结合FPGA可以对大量变量同时进行逻辑运算和赋值的特点,设计高性能的并行算法,可以实现计算速度和性价比的大幅提高。近年来,FPGA的逻辑资源和运算速度飞速发展,使得FPGA并行计算的应用领域不断拓展,同时FPGA的设计测试工具也在不断完善,使得更多数字电路领域之外的科技工作者可以涉足FPGA并行计算,为FPGA高性能计算的爆发性发展提供了条件。作为一个新兴的交叉领域,我们期待FPGA并行计算在包括智能科学技术在内的更多领域产生突破性的结果。