重构硬件操作系统BORPH提供的硬件进程概念和以硬件为中心的执行模型可极大地提高可重构计算平台的易用性。BORPH-N为BORPH的扩展系统,主要的扩展是支持在共享存储可重构计算平台上的运行。BORPH-N为硬件进程提供基于共享存储、符合Unix语义的高性能进程间通信支持:共享存储和信号量。利用这两项服务,硬件进程可与系统中其他所有软件进程和硬件进程进行交互。可重构计算的重要目标是利用可重构逻辑对应用的耗时部分进行加速,所以软硬件交互机制的效率至关重要。通过类似远程调用这种简单方式来提供这两项服务,软硬件交互频繁,开销较大,性能难以满足需求。BORPH—N使用的优化策略基于独立执行的基本思路进行设计。实验结果表明,BORPH—N所需硬件开销较小,为硬件进程提供的共享存储和信号量的效率逼近硬件平台的峰值,可以满足实际应用的需求。
可重构硬件操作系统BORPH是面向可重构计算系统设计的操作系统,目标是增强可重构平台的易用性,提出硬件进程来抽象硬件功能逻辑。正如软件进程运行于通用处理器(general purpose processor,GPP)上,硬件进程则在可重构硬件上执行。硬件进程与系统其他部分的通信符合UNIX语义的进程间通信机制实现。应用开发人员只需要开发硬件进程即可完成可重构平台应用的设计,BORPH将这种模式概括为硬件为中心的执行模型。
当前的BORPH实现中存在以下3个问题:
1)不支持共享存储平台,无法支持基于共享存储的进程通信方式。由于BORPH设计时面向的可重构平台BEE2为分布式存储,所以硬件进程与系统其他部分通信基于消息传递方式实现,效率较低。
2)软硬件进程问的数据传输仍然需要通用处理器控制,加重了GPP的负担,并且数据传输受限于GPP获取数据的速度。例如BORPH中提供的文件访问功能,需要系统软件负责从磁盘读取文件,而磁盘读取速度远远小于对系统主存的访问速度,这决定了该方法难以高效。
3)对硬件进程的系统服务支持是通过硬件模块的方式提供,不便于使用且难以扩展。
BORPH软件框架最早在分布式存储的BEE2平台上进行了实现,主要是面向海量信息处理等规模较大的并行处理任务。而普通用户平时使用的通常是基于PCIE总线的可重构处理平台,即FPGA以板卡形式插入普通PC的PCIE插槽中。由于FPGA可以通过PCIE访问系统主存,所以本文将该类可重构计算称为共享存储可重构计算机。与大规模的海量信息处理相比,该类可重构处理平台通常面向对进程间数据传输和同步的效率进行了优化,优化关键是减少GPP和FPGA之间通过中断机制交互的次数。当FPGA上运行的硬件进程需要进行数据传输和同步时,不需要GPP协助进行,而是独立完成,从而避免了GPP和FPGA之间频繁的交互。
1.BORPH-N简介
1.1 系统层次结构
本文首先将BORPH系统移植到由GPP和FPGA组成的可重构计算平台上,同时调整了FPGA片上逻辑的实现,添加了嵌入式标量处理核。因此硬件进程不仅包含硬件模块,还包括运行于该嵌入式标量处理核的软件部分。本文将经过移植和扩展的BORPH系统称为BORPH—N,图l为BORPH—N的层次结构图:
Fig.1 BORPH—N layer.
图1 BORPH—N系统层次结构图
在BORPH—N硬件层,GPP通过前端总线(front side bus,FSB)连接到存储控制集中器(memorycontrol hub,MCH)中,FPGA则通过PCIE连接到存储控制集中器中,两者共享系统主存。FPGA内部逻辑采取半定制方式设计,部分逻辑为基础硬件系统,主要包括嵌入式处理器、On-Chip RAM、片上总线以及PCIE总线接口等,用于支持BORPH—N系统的运行,其余部分为用户自定义功能模块,用于具体的功能逻辑实现。
在操作系统层,GPP上运行的系统软件包括标准的Linux内核以及一个内核的扩展模块:硬件进程代理。硬件进程代理主要负责管理FPGA,响应来自FPGA的系统服务请求。由于嵌入式微处理核的支持,用户可以方便地在FPGA上进行软件设计,所以BORPH—N中硬件进程除了包括硬件模块外,主要是指FPGA上的嵌入式软件部分。面向硬件进程的系统服务接口也以软件形式即微内核(microkernel)提供,而不是硬件形式。
图1中右侧上方为原始BORPH中硬件部分的层次结构,BORPH中硬件进程为一个硬件逻辑模块通过与一个或多个系统服务模块IOC相连来与系统交互(硬件进程的设计体现为通过硬件描述语言设计硬件模块)。在BORPH—N中,硬件进程的主体变为在FPGA内嵌入式处理器上运行的软件模块,该软件模块通过调用BORPH—N提供的软件接口与系统进行交互,用户也改为通过编写软件代码来设计硬件进程。硬件功能逻辑则根据硬件进程的实际需求进行设计,通过标准接口与FPGA片上系统相连,并且也由软件负责控制。本文认为BORPH—N的结构调整有以下优点:
1)从程序员视角看,为硬件进程提供的系统服务接口是软件形式的。用户通过在嵌入式处理核上设计软件,调用系统服务接口来与系统交互,与硬件接口相比,设计难度明显下降,并且接口扩展性也更好。
2)从内部实现看,硬件进程中的硬件逻辑部分接口标准。BORPH中硬件逻辑与IOC相连,接口不标准,BORPH—N中硬件逻辑与标准FPGA片上总线相连。标准接口可提高用户逻辑的通用性,并且FPGA厂商提供的库可降低用户设计硬件进程的困难。
1.2基于共享存储的进程间通信
本文为硬件进程提供了基于共享存储的进程间通信方法。共享存储符合System V的标准,软件进程可直接通过System V IPC访问共享存储。进程通过调用shmget()建立一个共享存储段。其他拥有合适权限的进程可以通过shmctl()对该共享存储段进行各种控制。进程可通过shmat()将创建后的共享段连接到本进程虚拟地址空间,并进行读写操作。每一个共享段都通过一个shmid进行标识。
当多个进程对同一个共享段进行写操作时,需要同步机制来确保正确访问。本文使用信号量来避免不一致以及访问冲突。与System V信号量相比,POSIX信号量实现和使用开销更低,所以本文采用POSIX信号量。进程通过sem_init()建立和初始化信号量,在访问共享资源之前通过sem_wait()来获取控制权,访问结束后通过sem_post()释放控制权。
本文为硬件进程提供一组包含上述函数支持访问System V共享存储和POSIX信号量的API。为了能够支持数据在主存和FPGA On—Chip RAM之间传输,BORPH-N增加两个API函数:cpy—from—vm()和cpy—to—vm(),分别用于将数据从虚拟存储拷贝到FPGA片上存储器和将FPGA片上存储器数据拷贝到虚拟存储。注意由于shmat()得到的虚拟地址,所以这两个API函数操作的地址都是虚拟地址而不是物理地址。嵌入式软件的设计基于该组API进行,对于系统中其他部分,硬件进程和软件进程是一样的,除非它执行在FPGA上。
硬件进程通常负责进行数据处理,初始化完成后通过一个持续执行的主循环来进行反复多批次的数据处理。在BORPH—N中,典型的程序结构如图2所示。初始化阶段建立共享存储段和信号量,这两个调用只会在初始化阶段发生一次(如果发生对多个信号量和多个共享存储段的访问,则初始化阶段也要发生多次)。然后是主循环,对共享存储的访问通过信号量进行互斥,其中关于信号量和虚拟存储的访问随着主循环反复执行,需要反复执行以读写数据,因而对硬件进程性能至关重要。
Fig.2 Typical program structure of hardware processes.
图2 硬件进程典型程序结构
2.基本实现
本节介绍BORPH—N系统的基本实现,分别介绍FPGA的硬件片上体系结构和软件部分的设计。
2.1片上体系结构
FPGA片上体系结构主要部件包括NIOS2,On—Chip RAM,PCIE Compiler,SGDMA(Scatter-Gather Dirdct Memory Access)和用户功能模块,这些部件通过Avalon总线相连。下面简单介绍这些部件的功能和配置。
NIOS2是Altera提供的广泛用于FPGA的软核处理器。该软核处理器的高度灵活性满足了成本敏感、实时等应用的各方面需求。本文使用的NIOS2为无操作系统支持的标准版本。
PCIE Compiler是Altera提供的PCIE总线与内部Avalon总线的协议转换器。本文配置的转换器为PCIE 2.0 1X的端节点,硬核实现,带Avalon—MM接口。支持Burst传输,读Burst负载最大为256 B,写Burst负载最大为128 B。
On—Chip RAM直接采用Altera提供的库实现。主要作为FPGA部分的软件管理片上存储器使用,提高应用执行效率。
用户自定义功能模块根据硬件线程的功能需求进行设计,必须能够与Avalon总线相连。用户通过NIOS2上运行的软件控制功能模块运行。
2.2软件
软件主要包括两部分:运行于GPP上的硬件进程代理和运行于FPGA中NIOS2上的微内核,这两部分协同工作为硬件进程提供系统服务支持。
1)硬件进程代理
操作系统对硬件进程的管理和服务支持以代理方式设计。每一个硬件进程都有一个软件代理进程与之对应。软件代理进程启动后负责配置FPGA并下载嵌入式软件代码,申请系统资源供硬件进程使用。最后注册中断响应函数,等待响应来自硬件进程的服务请求。对系统其他部分而言,代理进程即是硬件进程。
2)微内核
微内核运行于NIOS2上,负责嵌入式软件运行环境的初始化并为应用程序提供服务。初始化过程包括初始化C运行时库,注册中断信号处理函数,以处理来自GPP的中断信号,最后调用硬件进程标准人口点函数进入用户程序执行。在通用多核处理器上,用户进程需要请求系统服务时通过trap指令转入系统内核,系统服务本质上是对内核数据结构的操作。由于性能和数据结构复杂性的缘故,FPGA难以在本地完成硬件进程需要的系统服务,所以在本文基本实现中,所有面向硬件进程的系统调用都是以远程调用的方式实现,即请求由FPGA发出,GPP响应。GPP和FPGA之间的消息传递机制基于PCIE Compiler内的Mailbox实现,该Mailbox支持双向的数据传输和中断发送。
3.优化
根据1.2节中基于共享存储的进程通信方式,硬件进程会反复调用cpy—from一vm(),cpy—to一vm(),sem—wait(),sem—post()这4个函数来获取输人和写回输出。其他管理类函数如建立共享存储段和建立信号量在进程单次执行中通常都只执行一次,而这4个函数随着进程主循环的反复执行需要反复调用,所以其执行效率至关重要。本节针对这4个函数,以进程从共享存储获取输人数据进行处理为例,讨论本文优化的基本思路。
图3示出采用3种不同软硬件协同方式时FPGA获取输人数据并进行处理的过程。为避免繁琐,图3中省略了数据处理完成后写回输出数据的过程。输入数据通过访问共享存储段获得,使用信号量对共享存储段访问进行保护。整个过程分为两部分:获取输入数据和数据处理。图3中从左向右的箭头表示数据传输过程,折线段表示FPGA的数据处理过程。
Fig.3 Three types of software—hardware CO—operation.
图3 GPP控制、远程调用和FPGA控制的流程比较图
图3(a)表示以硬件为加速设备的软件进程的设计方法。该方法针对信号量的操作,与FPG没有关系,完全由软件执行。通过系统DMA来控制数据传输过程,注意该DMA位于系统总线上。数据传输之前软件需要对FPGA的接口寄存器进行配置,指示将要发生的数据传输。待数据传输完成后软件再次向FPGA发出命令,指示数据传输完毕。输入数据传输完毕后,软件向FPGA发出进行数据处理的命令,最后软件需要等待来自FPGA的执行完毕的信号。
图3(b)则是采用硬件进程概念的基本实现,表面上看信号量操作和数据传输均由NIOS2执行,但实际上所有的操作仍然是由软件完成,这种方法反而增加了GPP和FPGA之间的交互次数,降低了效率。
对比图3(a)(b)两种方法,可以发现它们的软硬件交互过程是相反的:图3(a)中需要交互时GPP主动发起请求,图3(b)中则是FPGA主动发起。图3(a)中由于主体程序运行在GPP上,关于系统的操作,如信号量等不需要发生交互,而关于FPGA的操作,如数据传输、数据处理等则需要发生交互。图3(b)中主体程序运行于FPGA上,关于FPGA本地的操作不需要发生交互,如数据处理,FPGA在获取到数据后可自行启动数据处理过程。其他包括信号量的操作等需要向GPP发出请求,并等待响应。
图3(c)则是本节将要讨论的优化实现,主体程序仍然在FPGA上运行,但信号量操作和数据传输都由NIOS2单独完成。考虑到NIOS2频率较低,只要保证执行在NIOS2上的代码非常短,即使相比在GPP上执行开销略大,但与取消两者之间的交互带来的性能提高相比则非常小。该目标的完成有两个条件:NIOS2能够独立地通过虚拟地址进行数据访问和独立地完成原子操作,从而实现对信号量的独立正确访问。下面分别对这两方面进行讨论。
3.1 独立虚拟存储访问
cpy—from—vm()和cpy—to—vm()类似,本文以cpy—from—wm()为例讨论优化方法。优化的cpy—from—um()实现分为地址翻译和数据传输两个过程。第1个过程将虚拟地址翻译为Avalon内部总线地址,这一步根据页表和所需要访问的虚拟地址对PCIE Compiler进行设置,以保证通过内部Avalon地址对PCIE Compiler的访问能够正确地映射到对主存物理地址的访问。第2步控制数据在on—ChipRAM和PCIE Compiler之间传输。
Linux将可用的物理存储器分割为4 KB的页面。PGD(page global directory)和PTE(page tableentry)两级组织的页表用来描述虚地址与物理地址的映射关系。虚拟地址分为3段,前两段分别是指向PGD和PTE的指针,最后一段是偏移量。PGD和PTE两个表格都存储在内核空间,物理地址是虚拟地址减去0xC0000000,所以FPGA可以通过物理地址直接访问PGD和PTE,完成虚拟地址到物理地址的翻译。
图4示出FPGA进行地址翻译的过程,该过程将虚拟地址映射为本地Avalon地址,这样NIOS2或Avalon总线上的其他部件通过访问该本地地址即可访问到所需的进程虚拟地址。给定需要访问的虚拟地址,首先查询PGD和PTE来得到物理地址,物理地址的高22位即为物理页的首地址。该起始地址会写入PCIE Compiler的地址转换表中。然后,所有来自Avalon访问PCIE Compiler的访问都会自动转换为对物理地址的访问事务,每次只有4 KB的地址被映射。
Fig.4 Translation of local address to host physic address.
图4 本地地址向主机物理地址的翻译
PGD和PTE中的空人口意味着发生页错误。由于处理页错误的过程比较复杂,FPGA难以独立完成,本文采用与EXOCHI中CEH类似的方式处理页错误。关于该页错误的消息会发送GPP,当页错误发生,GPP会代替FPGA处理该页错误。
第2个过程在PCIE Compiler的支持下较容易完成。PCIE Compiler将读写请求自动转换为对PCIE总线的读写请求,就能够完成数据从On-ChipRAM到主存的传输过程。On—Chip RAM和PCIECompiler之间的数据传输过程可通过简单的数据拷贝完成(如memcpy)。但这种方法效率非常低,由于数据传输的性能至关重要,所以本文在FPGA内添加了SGDMA组件来提高数据效率。
在传统多核处理器中,Cache一致性保证了多个处理核具有相同的存储视图。当前的MCH通常支持Snoop存储一致性协议,即保证主存GPP内部Cache的一致性,也保证了FPGA对主存访问的正确性。但FPGA内部的On—Chip RAM无法与GPP内部Cache保持一致,所以硬件进程必须负责管理On—Chip RAM。
3.2定制同步存储单元
sem—wait()操作首先判断信号量是否大于0,若大于0则将其减1,继续执行,否则等待。sem—post()将信号量加1,并唤醒所有等待该信号量的进程。本文将这两者统一为1次对信号量的原子访问,以及可能的堵塞等待或是唤醒操作。如果对信号量的访问可在本地高效进行,则可极大地减小sem—wait()成功以及进行sem—post()的延迟时间开销,因为sem—wait()成功时不需要等待,sem—post()时只需向GPP发出信号,不需要等待该信号返回。而如果sem—wait()不成功,则时间开销是不可避免的,硬件进程将进入等待GPP信号的状态。
POSIX信号量实际上是1个16B的整型变量,对其访问必须满足原子性要求,所以本文优化的关键问题就是FPGA如何对1个16 B的整型变量实现原子操作。常见的硬件原语操作支持包括compareand—swap,fetch—and—add等,原语操作的关键在于保证读和写之间的原子性。例如fetch-and—add,实际是1次读访存操作,然后进行加法操作并将结果写入存储单元,必须保证读和写之间没有其他指令对该单元进行访问。多核x86体系结构硬件上对该原子性的支持通过前端总线的锁定信号FSBLOCK实现,该信号指示一个原子事务需要执行。
而在本文的硬件平台中,由于FPGA是一个PCIE端设备,不具备锁定前端总线的能力,所以无法以相似的方法实现对系统存储单元的原子性操作。本文提出通过FPGA提供一种特殊的存储单元用于支持原子操作的方法,将该存储单元称为MutexRAM。该存储单元实现于FPGA内部(因为FPGA是整个硬件平台中设计人员唯一能修改的部分),并且映射到系统存储空间,保证GPP可以通过PCIE总线访问。该单元设计的目标是GPP和NIOS2都可以对该单元进行锁定,从而支持两者通过该单元进行互斥。
Mutex RAM的设计依赖于MCH对PCIE设备访问的一种特征。GPP进行锁定操作时,如果目标地址指向PCIE设备,则MCH会将该请求转换为读锁定(read lock)事务发往PCIE设备。当发生写操作时自动解锁,否则会发出单独的解锁事务包(completion locked without data)根据这一特征,Mutex RAM设计如图5所示。RAM中每个32位数增加1位锁定位,0表示未锁定,1表示锁定。双端口访问,端口A提供普通的读写访问,写操作附带解锁含义,端口B的读操作实际为读锁定,写操作为解锁。当收到来自GPP的读锁定请求和解锁请求时PCIE Compiler访问Mutex RAM的端口B,否则访问端口A。两个端口的访问会被自动排序以避免冲突。如果读请求和读锁定请求访问的存储单元已经被锁定,则该存储访问操作会被堵塞。这样的设计可保证GPP和FPGA都可以实现对Mutex RAM的原子操作。
Fig.5 Diagram of dual ports mutex RAM.
图5 双端口Mutex RAM结构图
4.性能评测
本文完成了BORPH—N系统的基本实现,并进行了两项优化工作。建立实验平台时采用的通用处理平台配置为:Intel E5200,4 GB DDR2内存。FPGA主板采用ARRIA II GX芯片,片上系统综合频率为50 MHz。FPGA芯片上各部件资源使用情况如表1所示。这些资源的占用分为两类:一是任意方式使用FPGA都不可以避免的开销,包括PCIECompiler和On—Chip RAM,因为FPGA必须依靠前者以便于PCIE总线相连,后者则是进行数据处理必须的缓冲;第2类是用于支持BORPH—N运行的部件,包括NIOS2,SGDMA和Mutex RAM,这三者对ARRIA II GX芯片逻辑资源的占用率非常小,由于控制Burst传输需要大量缓存,所以使用存储块资源较多。
Table 1 Resource Utilization of Hardware Components
表1 FPGA片上各组件资源占用
本文分别对BORPH—N系统的远程系统调用、虚拟存储访问和信号量访问3个方面进行了详细的性能测试。主要测试手段是在FPGA内硬件系统中添加性能计数器(performance counter)来统计时间开销。在分析数据传输效率时为了得到更加精确的时间开销信息,加入SignalTab探针。所有时间单位均为FPGA的时钟周期。
4.1基本实现的远程系统服务调用
本文首先对调用远程系统服务的开销进行了测试,以shm—get()为例,该过程包括从NIOS2发出请求到GPP得到完成服务请求的信号为止,进行1000次调用远程系统服务,平均时间开销为1980时钟周期。
测试结果如图6所示,NIOS2通过PCIE Compiler中的Mailbox向GPP发出请求,该请求从被发出到被GPP响应时间开销大约为600时钟周期。Mailbox为PCIE Compiler中的一组寄存器,对该组寄存器进行写操作,PCIE Compiler将会向GPP发出中断信号。图6中REG Write即是指该写操作,IRQ指PCIE Compiler向GPP发出的中断信号。紧接着为GPP完成实际系统服务的时间,“Real”shm—get是指GPP执行真正的共享存储段建立工作,只需要大概800时钟周期。最后GPP也通过向PCIE Compiler内的Mailbox进行写操作来向N10S2发出请求完成的信号,只是该写操作通过PCIE进行。这些开销中通过PCIE总线进行读写占了很大比例,由于数据传输量非常小,仅仅为7个参数和1个返回值,总线传输效率非常低。这表明调用远程系统服务是比较低效的,所以在实际的应用程序中不应该大量反复使用,而应该只在初始化或是结束时进行调用。但这并不影响通过共享存储进行进程间通信的实用性,因为一旦进程通过将共享存储段链接到本进程的地址空间后,对这些数据的访问就不需要再通过远程调用系统进行服务。
图6 远程系统服务调用流程
4.2高性能信号量操作
本文对NIOS2和GPP对Mutex RAM内信号量进行1次fetch—and—add原语操作的时间开销进行了评估。NIOS2内进行该原子操作时间为10时钟周期,GPP为60时钟周期。这表明两者进行同步的开销远远小于进行1次远程系统服务调用的开销。NIOS2和GPP对信号量的访问均为1次读操作和1次写操作,不同的是NIOS2的读写操作通过FPGA内Avalon总线进行,而GPP则是通过PCIE总线进行,所以时间开销相对较大。
4.3虚拟存储访问
按照本文设计的虚拟存储访问机制,对单个物理页即4 KB的存储进行访问的时间开销包括3部分:地址翻译、可能的页错误处理和实际的数据传输过程。前两者的时间开销在任何时候都基本固定,变化很小。
地址翻译过程比较简单,由2次NIOS2通过PCIE对系统存储的访问构成,为200时钟周期。页错误处理过程的开销与3.1节中1次远程系统服务调用类似,为1500~2000时钟周期。通常使用FPGA进行加速的应用,不同模块之问进行数据交互时有两个特点:大批量连续的数据传输和固定的数据存储地址。由于每次进行数据交互的物理内存地址固定,页错误只会在第1次发生,后面就不会反复发生。
实际数据传输过程为On—Chip RAM与系统存储之间的数据传输,在本文系统中等价于On—Chip RAM与PCIE Compiler之间的数据传输。数据传输过程可由NIOS2执行简单的存储拷贝函数memcpy完成,也可由SGDMA控制完成。表2列出了利用两种方式在传输不同规模数据的时间开销,单位为时钟周期,通过进行1000次数据传输,对时间开销取平均值得到。P是指PCIE Compiler,O是指On-Chip RAM,第1行数据是指数据传输时每个PCIE事务数据负载的大小,单位为Byte。
Table 2 Two Types of Data Transfer
表2 两种数据传输方式的比较
简单调用存储拷贝函数memcpy无法利用PCIE Compiler的Burst传输能力。结果显示在On—Chip RAM和PCIE Compiler之间传输4 KB数据速度非常慢,并且读写次数也非常多。这是由于对PCIE Compiler的每次读写实际上都转换为对PCIE总线的访问,也就是形成单个的PCIE事务,而负载却非常小,通常仅为4B,这使得传输效率非常低。
结果表明使用SGDMA后效率获得大幅度提升。PCIE Compiler支持的Burst读最大长度为256 B,Burst写最大长度为128B,结果表明SGDMA充分利用PCIE Compiler的Burst传输能力。由于SGDMA可以自行控制多个传输的进行,所以当数据量大于4 KB时,多次DMA之间时间开销非常小,从而能保证数据传输率保持不变。
从结果中可以发现读操作开销略大于写操作,读操作的额外开销来自存储一致性协议。在FPGA对主存进行写操作时不需要等待,总线制器将CPU内Cache置为失效即可。但在FPGA进行读时如果最新的数据在Cache内,则需要CPU先进行Cache的清空操作,将数据写回主存,该开销为300时钟周期。该开销实际上为存储一致性协议的开销。
4.4性能分析
本文从两个方面来分析BORPH-N的性能:一方面是数据传输通道的带宽利用率;另一方面是获取一批次输入数据的时间开销。
由于BORPH—N中硬件进程通过FPGA内部的SGDMA控制数据在主存和FPGA的On—ChipRAM之间传输,而不是通常的系统DMA,所以考察这种方式是否能够充分利用数据传输通道的带宽非常重要。
图7为利用SGDMA部件来控制PCIE Compiler和FPGA的On—Chip RAM之间的数据传输的性能。该图通过SignalTab的探针考察SGDMA的读写端口得到,4行信号分别为SGDMA的SGDMA—READ(读使能信号)'SGDMA—READ—DATA(读数据信号),SGDMA—WRITE(写使能信号)和SGDMA—WRITE—DATA(写数据信号)。
Fig.7 Signals of SGDMA controlling data transfer.
图7 SGDMA控制数据传输读写信号
图7分为左右两边,分别测试了双向数据传输的效率。左侧部分可以清晰地看出SGDMA首先发出读使能信号,停顿后(即存储一致性开销)有16组读数据到达,每组为256 B。读数据到达的同时,SGDMA将数据同时写入On—Chip RAM。右侧也类似,首先发出读使能信号,由于是读On—Chip RAM,所以没有延迟。对On-Chip RAM的读操作达到了On-Chip RAM的峰值性能。同时SGDMA将数据写入PCIE Compiler,从图中可以清晰地看出写操作分为32组burst数据,每组128B。
图7表明利用SGDMA控制数据传输,已经达到了PCIE Compiler的峰值传输性能。在50 MHz的频率下,读写带宽分别为974 Mbps和1 187 Mbps。PCIE 2.0 lx的峰值带宽为5 Gbps。该数据表明当前BORPH—N的数据传输带宽利用率是较低的,但要强调的是数据传输的瓶颈是PCIE Compile以及FPGA片上系统过低的频率。优化PCIE Compiler设计和提高片上系统频率是提高数据传输带宽的两个途径。
此外考察获取一批次输人数据的时间开销,为简单起见假定输入数据为4 KB,首先考察BORPH—N系统中硬件进程获取4 KB输人数据的开销。开销包括两次信号量操作,时间开销为20时钟周期,1次地址转换时间开销为200时钟周期。考虑正常运行过程中不会再发生页错误,所以不计人页错误处理开销。这些开销加上数据传输开销,综合的读写传输率为861 Mbps和1 024 Mbps。
首先与原始BORPH系统中硬件进程获取输入数据的速率进行比较。由于原始BORPH仅为硬件进程提供了访问文件系统的方法,该方法必然受限于磁盘访问的速率,而普通的磁盘数据读写速率仅为560~720 Mbps。该性能是磁盘数据读写的峰值,并且还没有考虑交互的开销。然后与传统的加速器方式进行比较。按照图3(a)所示,进行1次数据传输需要1次GPP和FPGA之间的交互。该交互包括GPP访问1次FPGA,以及FPGA返回1次状态信息。前者开销为200时钟周期。后者可通过GPP轮询或是中断信号处理的方式实现,以效率较高的中断方式为例,参照4.1节实验数据,时间开销为600时钟周期。需要注意的是这些交互开销的绝对时间并不会随着FPGA片上系统频率的提高而减少,因为这些开销是来自PCIE总线以及GPP方面。实际数据传输虽然由系统DMA控制,但根据上述分析,数据传输的瓶颈在于PCIECompiler,所以传输开销必然与通过SGDMA控制得相同。因此总的读写带宽为660 Mbps和751 MbpS。可以发现BORPH—N与之相比读写带宽分别提高30%和36%。并且这里还没有考虑启动FPGA进行处理时还需要进行的1次GPP和FPGA之间的交互。
5.相关研究与总结
HThread面向片上多处理系统设计,与BORPH思想较为相近,不同的是HThread扩展了线程概念,丽BORPH扩展了进程概念。HThread将多线程编程模型扩展到可重构计算中,系统将硬件逻辑抽象为硬件线程。HThread基于微内核的概念设计,由一组功能模块包括线程管理器、锁管理器、共享存储管理单元等构成系统内核,这些功能模块可以实现为通用处理核上的软件,也可以实现为挂载在系统总线上的硬件逻辑。软硬件线程通过不同的接口访问这些功能模块,也就是访问系统服务,线程之间通过系统服务实现协同。
Saldana等人介绍了通过MPI进行软硬件交互的方法。硬件模块通过系统提供的TMD-MPE模块来与系统其他部分进行交互。使用MPI来抽象软硬件之间的交互接口具有非常好的特性,如支持软硬件模块的无缝替换。本文介绍的节点内进程间高效率通信方法可以支持TMD-MPI在单节点内不同进程之间的通信。
HybridOS和OpenFPGAE都以加速器方式进行GPP和FPGA之闻协同。该方向的研究新趋势也是对操作FPGA的编程接口进行规范化。HybridOS的方法是统一FPGA内部逻辑的框架结构,以类似访问文件的方式访问FPGA逻辑的缓冲,试图将对FPGA的操作统一到一般的文件操作方式。OpenFPGA则试图将FPGA统一为一类标准的设备,设计具有统一接VI的驱动程序,不同类型的FPGA逻辑都实现该接口,保证上层软件的一致性。
考虑使用新型高级编程模型来开发FPGA应用也一直是学术界的研究热点。最近的研究包括将CUDA,OpenCL等面向众核的编程模型引入到FPGA的应用开发中。FCUDA利用CUDA作为FPGA设计的编程模型。FCUDA可将CUDA程序中的粗粒度和细粒度并行高效地映射到可重构逻辑上。FCUDA基于高级综合工具AutoPilot实现,通过源到源编译器实现CUDA代码到AutoPilot代码的转换。
国内学术界也有大量研究关注如何简化可重构计算中的软硬件协同问题。马吉军在其学位论文中讨论了将线程概念扩展到可重构计算中的方法,并将软硬件协同设计转换为多线程应用开发。与本文不同的是,该工作的底层平台专注于片上可重构计算系统,以支持硬件线程和软件线程之间非常紧密的耦合关系。
本文将BORPH移植到普通用户最易获得的由FPGA板和通用PC构成的可重构计算乎台上,并对硬件进程概念进行了扩展,降低了硬件进程设计难度。硬件进程设计难度的降低体现在两个方面:一方面是与系统交互部分通过软件接口面不是硬件接口,编写软件程序来调用系统接口,显然比设计硬件逻辑来连接硬件接口更为容易;另一方面是功能逻辑部分,由于接口为标准FPGA片上总线接口,有大量厂商提供的库支持方便了设计。基于独立执行的基本思想,提供了性能优化的软硬件进程间通信机制。