



计算机最核心的部件就是计算单元,我们通常会用到的计算单元种类有CPU、GPU、FPGA和ASIC(专用集成电路)四类。CPU是最常用的计算部件,大多数情况下,服务器或边缘设备都会由CPU提供通用运算和数据处理能力。如今的计算机基础架构均采用的是冯·诺依曼架构,就是以CPU和存储为核心设计和定义的。冯·诺依曼架构同时也是存在时间最久的计算机架构。早期的GPU是专门设计用于计算机图像处理的通用芯片,采取单指令多数据流(SIMD)的方式处理浮点和整数运算,拥有非常强的并行计算和并行数据处理能力。
FPGA和ASIC都属于专用数字芯片,不同的是,FPGA是基于可编程门电路设计开发的一类可以通过编程改写内部功能的芯片。而ASIC则是为专门领域和任务设计的数字芯片。
无论是云计算还是边缘计算,这些通用和专用的计算硬件都在发挥着各自独特的作用。在设计边缘计算系统时,我们有必要了解不同计算组件的特点,并根据应用场景和需求的不同,而选择不同的核心运算硬件为基础的边缘设备。
美籍匈牙利数学家冯·诺依曼于1946年提出了存储程序的理论,将计算机程序作为数据对待。程序及该程序处理的数据用同样的方式存储,然后顺序执行。另外,冯·诺依曼体系还将二进制数据存储和运算作为计算机电路和元器件设计的基础,好处是大大简化了电子计算机逻辑电路和存储器件的设计,更加符合电路的工作特性。上面提到的冯·诺依曼体系如今看来并没有什么,但是在计算机刚刚发明的时期确实起到了非常重要的指导作用。
传统的计算机系统可以分成哈佛体系(程序指令和数据分离存储)和标准的冯·诺依曼体系(程序指令和数据共享存储),严格来说,以CPU和GPU运算单元为核心的计算机系统都属于冯·诺依曼体系,而以CPU作为中央处理器的计算机架构是最经典的冯氏硬件架构。冯·诺依曼体系架构包含运算器、控制器、存储器、输入设备和输出设备,如图2-1所示。
图2-1 冯·诺依曼体系架构
运算器的全称是算术逻辑单元(ALU)。在ALU中,通常集成了执行算术运算和逻辑运算的半导体单元,包括整型加减法功能单元、浮点数计算单元、各种逻辑运算功能单元等。其作用就是把输入的数据根据指令放到合适的运算单元处理,并输出计算结果。控制器是计算机的指挥部,负责按顺序或按转移标志的要求,从内存中读取程序指令并交给ALU运算,同时根据指令中的数据地址读取指令计算需要的数据并存入ALU高速寄存器,计算完成后将计算结果存入指令指定的内存地址。控制器除内存数据读取和计算控制功能外,还负责输入/输出设备的数据读写和访问控制。通常,CPU厂家会将控制器和运算器的功能合并到一块芯片中,称为中央处理器单元,也就是CPU。现在CPU都是由上亿晶体管构成的复杂集成电路,由专业的芯片加工企业负责生产、封装和测试。
计算机系统总线通常分为外部总线和内部总线两类。计算机外部总线用于设备与设备之间,或者设备与计算机之间的连接,如以太网就算是一种外部通信总线,这在边缘计算通信的章节会做详细的介绍。图2-2所示是计算机内部总线的示意图,计算机内部总线分为控制总线、数据总线和地址总线三类。控制总线用于传输控制信号,负责将指令和控制信号从CPU发送到各个计算机组件,协调和控制计算机的操作。数据总线用于在CPU、内部I/O及存储之间传输数据。数据总线和地址总线通常都采用并行通信的方式,并行的位数由CPU的运算位数决定。
图2-2 计算机内部总线
例如,8086和8088这两种早期的通用芯片,8086为16位处理器,能够处理16位二进制数据的计算,那和这种CPU配套的数据总线和地址总线就是16位的总线结构。8088处理器的执行单元和计算单元也是16位的,芯片基本结构和8086一致,不过为了降低成本和简化电路设计,其采用了8位的数据总线和地址总线,使得8088的性能不如8086,内存直接寻址范围也大大小于8086处理器。但是, 8088由于采用了8位数据总线和8位地址总线,使得其数据总线和地址总线是完全分开的,而8086的数据总线和地址总线是在一条16位总线上复用的。
数据总线是双向的,可以在CPU、内存和I/O设备间传输;而地址总线是单向的,从CPU发出,内存只是接收地址总线的数据,然后根据地址信息在内存中找到存储位置后进行读写操作。总线结构在小型计算机上使用得非常普遍,但是它的缺点也非常明显。每个系统时钟周期,只能在数据总线上传输一次数据,这就限制了系统的并发能力。不过,总线结构的优点是结构简单、稳定性高、成本低,其在通用计算机系统领域中使用得比较普遍。我们的PC、手机、平板都是采用的总线数据传输方式。对于大量的小型边缘设备来说,这种通用计算设备占据了所有设备中的绝大多数。
虽然边缘计算与高性能计算机(HPC)这个领域的交集不多,但是为了完整性,还是有必要介绍高性能计算机和高端存储的总线架构。如果大家碰到这些“特种装备”,就能够理解为什么它会比普通的商用计算机快得多,同时价格也贵得多。
其实高性能计算机和高端存储所使用的单个存储设备和单个芯片的性能不一定比通用CPU高。高端存储系统能够达到非常高的吞吐量和读写性能是因为依靠了复杂的连接架构,如早期采用ASIC芯片的交换架构和矩阵直连的架构,目前比较常见的是全分布式架构。华为的OceanStor 18000就是全分布式架构,基于PCIe串行连接,最多支持16路控制器。高性能计算机也有用全光纤连接运算器和内存的,能够确保多路CPU可以同时读写内存数据和进行逻辑运算,大大增加了计算机的并发性能和吞吐量。
下面我们看一下对于CPU性能来说比较重要的几个因素。
1.复杂指令集(CISC)和精简指令集(RISC)
CPU架构可以分为复杂指令集和精简指令集架构。CPU的指令集就是CPU能够处理的运算操作的集合,包括算术运算和逻辑运算这两类。复杂指令集和精简指令集的设计思路是不一样的。X86体系是比较典型的复杂指令集,特点是提供了很多能够完成复杂功能的指令,一条指令可以完成比较复杂的运算和处理,这些指令往往是某种高级语言功能的硬件实现。X86体系的CPU就内化了很多这方面的功能,比如大量的浮点计算和逻辑变换等功能。
像ARM、MIPS这些架构的CPU都采用了精简指令集。精简指令集架构是受到加州大学伯克利分校关于CPU指令集的研究启发而研制的。这个研究发现,当时(1979年)的复杂指令集CPU运行的程序中,80%的指令仅仅占了整个指令集系统中20%左右的指令数量。其中最常用的往往是加法、存取数据这些最简单的指令,复杂指令不但增加了指令解析的复杂度,而且还使芯片复杂度和能耗上升。于是很多研究机构和企业开始尝试设计和制造精简指令集的CPU,这些CPU通常只保留程序运行最常用和最基本的指令。
采用了精简指令集设计的ARM架构处理器是目前移动设备和嵌入式设备的主流架构。在很长一段时间内,产业界在涉及需要强大数据处理能力和性能的领域中,倾向于使用复杂指令集的X86架构CPU。而在需要低功耗、低计算密度的情况下,倾向于选择精简指令集架构的CPU,比如ARM架构和MIPS架构的芯片。但是,苹果公司在2020年的“双十一”推出的M1芯片,证明了ARM架构的精简指令集CPU也能够达到甚至超过X86这种复杂指令集体系芯片的性能,而且更省电(只有相同性能X86架构芯片耗电量的30%)、发热更少。这对于未来的边缘设备来说是一个好消息。
M1芯片的出现,给CPU的发展指出了一个以RISC指令集架构为基础的高效和节能的发展方向。同时,M1芯片也是迄今为止集成度最高的系统级芯片(SoC),其整合了8个CPU内核、8个GPU内核、16核的机器学习加速器、高速闪电USB接口,以及各种安全模块和I/O控制系统。
2.CPU的流水线深度和分支预测
CPU的流水线(Pipeline)深度和数量也会影响CPU的性能,CPU的运算一般分成几个步骤,分别是取指令、译码和执行。最初CPU的设计人员把这三个步骤分开,于是就有了三级流水线。ARM7就是采用这样的三级流水线,ARM9增加了访存和回写两个步骤,形成了五级流水线。不过,五级流水线存在寄存器冲突的问题,会造成流水线等待。ARM10为了解决寄存器冲突问题,用预期和发送两个步骤取代了取指令步骤,成为六级流水线。ARM11增加了一个预取步骤和一个转换步骤,使流水线深度变为八级,整个内核的指令吞吐量提高了40%。最新的ARMv9架构将流水线深度控制在了10级。
理论上来说,增加CPU的流水线的级数,也就是深度,同时提高CPU的工作频率,就能够提高CPU的处理能力。这样每一级运算需要消耗的时间更少,整体处理速度就会越快。对于Intel和AMD的CPU设计,曾经为了提高性能和追赶摩尔定律,采用过不断增加流水线深度,提高计算机工作频率的升级路线。
在Intel的Pentium系列CPU的时代,CPU的流水线级数一度上升到了39级(Proscott架构)。这造成了CPU核心设计越来越复杂,多出的步骤和更高的主频也造成了CPU核心的功耗越来越大,而且一旦运算分支预测失败或L1/L2缓存未能命中,从内存读取指令并重填流水线会造成更严重的性能损失。Intel意识到这种升级路线在未来是无法持续的,因此后来采用了以色列团队研发的Conroe架构,通过增加并行部件(超线程技术、乱序执行和多发射)和内核数量的方式提高性能。这也成为2005年至今,所有主流CPU提升性能的路径。
CPU的分支预测,也是一个非常重要的提高CPU处理性能的方式。通过分支预测的方法,可以在程序分支还没有完成判断的情况下,预测一个可能执行的分支,并将相应的指令放入执行队列中,这样可以避免判断和循环产生分支时,指令流水线的等待。现在指令预测可以做到非常高的正确率,但是如果预测失败,也会产生比较高的开销。这就需要CPU的设计人员和专家尽可能提高准确性,使预测失败造成的损失远远小于预测成功带来的性能提升。
3.内核数和多线程
最近十多年,CPU的发展主要是通过增加芯片的并行处理能力来提高整体的计算和处理能力。一种方式是增加CPU的内核数量,AMD已经将这条路线走到了64核的地步,最新的AMD Ryzen ThreadRipper Pro 3995系列就使用了64内核128线程设计。这里有一个挺奇怪的地方,64个内核不是应该只能运行64个线程吗?为什么可以支持128个线程?这就是X86 CPU中常用的超线程技术了。在每个物理内核上会有两个或多个逻辑内核,如果一个逻辑内核上的线程等待或空闲,另一个逻辑内核就可以开始执行。超线程技术可以更加充分地利用“闲置”运算单元,在普通的非计算密集型任务处理中,CPU性能可以提高20%~30%。
不过,这种超线程技术并没有在ARM架构的芯片中采用,原因有几点,其中一点是,在实际的测试中,比如游戏应用,CPU超线程技术会大大增加CPU核心的负载,但是往往只能提升很小的性能,这对于ARM架构芯片主打的低功耗移动设备和物联网嵌入式设备来说并不一定是最优的选择。主流的移动设备ARM架构芯片研发厂商,如高通、三星、华为和联发科等,通常都采用多个高性能ARM核心和多个低功耗核心的组合架构。如图2-3所示,高通骁龙888 SoC的Kryo 680 CPU就由1个Cortex-X1加上3个Cortex-A78高性能内核,再加上4个Cortex-A55低功耗内核构成。构成了高性能和低功耗搭配的组合,可以根据实际的应用运算负载,决定采用低功耗内核还是高性能内核进行处理。
图2-3 高通骁龙888 SoC的Kryo 680 CPU结构
提高CPU性能的另外一种方式就是乱序执行和多发射(也称为超标量),通常CPU会同时读取多条指令放入Pre-Decode Buffer中,然后通过指令解码器对指令进行识别,并将指令放到Reorder Buffer中,根据Buffer中指令的依赖关系,重新安排执行顺序。乱序将不同的指令根据依赖关系重新调整执行顺序,然后送入CPU指令流水线处理。乱序执行可以更加充分地利用CPU的处理能力,减少运算器等待时间,提高CPU的处理效率。
超标量就是指CPU在一个时钟周期能够最多接收几条指令同时处理,由于CPU内核的ALU由多个运算和逻辑单元组成,如果同时有几条指令,可以分别送入不同的运算单元去处理。无论是X86还是ARM架构的CPU,都采用了乱序执行和多发射的技术来提高并发处理的性能。但是,X86这类复杂指令集架构在乱序执行和多发射的更进一步应用中,受到了其本身的限制。
首先X86的指令长度是不固定的,位数从1个字节到15个字节都有可能,而且指令数量多,这就使指令解码器复杂度增加。最新的X86或X86-64的芯片通常只有4个到5个指令解码器,而且X86架构难以扩大Reorder Buffer。因为设计Reorder Buffer必须考虑到指令的长度,每个Buffer单元必须大于等于16字节,这样导致过大的Buffer会大大增加芯片的面积和功耗。最新的X86的Reorder Buffer最多只有256个。
上述这些原因制约了在X86的CPU上扩大Reorder Buffer的数量,但是这些限制对于精简指令集的ARM架构处理器的影响就小得多。采用ARM架构的指令集长度固定,都是4个字节。同时,指令数量少,指令简单,这使得指令解码器和乱序执行的分析器都相对简单,能够通过增加Reorder Buffer和指令解码器的数量来提高性能。苹果公司最新研制的M1芯片之所以有如此强劲的表现,很大程度上就是因为其采用了600个Reorder Buffer和8个指令解码器,这使得M1芯片的整体处理能力,尤其是对于现在的复杂应用程序和多任务操作系统来说非常重要的并发能力大大增强了。未来RISC架构的芯片在处理和存取指令的速度、并行能力和简单性等方面的优势将会越来越明显,也许会成为下一代CPU技术革新的主要动力。
如图2-4所示,Core i9-10900K这样的复杂指令集CPU核心为了处理众多指令和支持复杂的流水线结构,其CPU内核占据了大量的芯片空间,同时能耗也非常高。
图2-4 Intel Core i9-10900K CPU芯片结构
而以ARM A76和A55内核为CPU核心的华为麒麟990 SoC的CPU内核占的面积和复杂程度就要小得多(图2-5),这也使得这样的芯片能够进一步集成其他更多的功能,例如,5G/4G通信模块、嵌入式神经网络处理器(NPU)、媒体处理模块、系统缓存(Cache)及GPU内核等,同时整体的功耗也会比Core i9-10900K小很多。很多物联网处理设备其实需要的计算能力并不是很高,像树莓派4采用的博通BCM2711 SoC使用了四核64位的ARM Cortex-A72架构CPU,已经足够运行大部分Linux环境下的服务程序了。
图2-5 华为麒麟990芯片结构
CPU是最重要也是最常见的通用计算核心,在运行通用计算和事务处理任务时,非常高效。然而,如果遇到需要进行大量并行运算的情况,CPU虽然也能处理,但是由于ALU数量的限制,以及本身架构设计的问题,其处理任务效率相对来说就比较低了。GPU(Graphic Processing Unit)最早是专门用于进行二维或三维图像处理的集成电路。在三维图像渲染和位置计算中会涉及大量的矩阵运算,这些矩阵运算的计算点位众多,而且为了提高速度,需要大量的同质运算单元同时进行处理。
如今越来越多的应用,包括边缘计算应用,需要使用机器学习。而机器学习模型的训练和推理同样也需要大量的并行、整型或浮点数计算,这正好是GPU所擅长的方向。那么,为什么GPU在人工智能时代能够发挥出这样的能量呢?这还得从GPU的设计理念和架构谈起。用来度量并行技术能力的单位是FLOPS、GFLOPS和TFLOPS,高性能计算机通常也会用这些度量单位来表示运算能力。FLOPS是Floating-point Operation Per Second的缩写,指的是每秒钟处理浮点运算的数量,GFLOPS就是每秒处理多少个10 9 次浮点数计算,1TFLOPS则等于GFLOPS的1000倍,即10 12 次浮点数计算。目前,高端游戏GPU Geforce RTX 3090可以达到35.7TFLOPS的单精度浮点数计算能力。作为高端专业GPU的A100则可以达到19.5TFLOPS的单精度浮点数计算能力和9.7TFLOPS的双精度浮点数计算能力。
除人工智能应用和图像处理外,在大数据的处理、工业仿真、物理仿真、复杂系统预测等领域中,也需要使用到GPU强大的并行运算能力。GPU本质上是一个异构的多处理单元芯片。GPU中的每一个处理单元和CPU核心类似,有取指令功能、指令解释器、ALU及FPU(浮点处理单元)和结果输出队列。
图2-6所示的NVIDIA Pascal架构内部由大量的并行运算单元组成,图中的每一个小方块代表一个CUDA(统一计算设备架构)核,每个CUDA核中拥有一个整型算术单元和一个浮点算术单元。通常,这个最基本的运算单元也可以称为流处理器(SP),多个SP再加上一些其他的资源,如存储、共享内存和寄存器等,可以组成一个多流处理器(SM)。
图2-6 NVIDIA Pascal架构的GPU结构
GPU在逻辑上的组织关系为:最小的单元为一个线程(Thread),多个线程组成一个块(Block),多个块组成一个网格(Grid)。
GPU在物理上的组织关系为:最小的单元为一个CUDA Core(ALU),又称为SP,多个CUDA Core组成一个SM,多个SM组成图形处理集群(GPC)或称为设备(Device)。
由CUDA中的GPU在软硬件上的组织关系,可以得到映射关系为:一个Thread对应一个CUDA Core,一个Block对应一个SM,一个Grid对应一个GPC。当然,在实际的程序中,可能并不是这样一致的对应关系。
如图2-7所示,采用Volta架构的NVIDIA A100专业显卡的每个SM含有64个FP32浮点运算单元、64个INT32整型运算单元、32个FP64浮点运算单元和4个Tensor Core单元。整个显卡拥有108个这样的SM,每个SM拥有8个512bit的二级缓存控制器。Tensor Core是专门用于矩阵计算的内核,比普通的32位浮点运算单元的性能快12倍。每个SM中有4个Warp Scheduler,用于在SM的一个分块中计划并执行并行计算任务。
图2-7 NVIDIA A100中的一个SM结构
我们可以发现,整个的GPU架构就是由大量的重复运算单元组成的,而且这些重复的单元由SP、SM、GPC等几个层次组合在一起,形成了一个多单元、多层级的结构。我们在显卡多线程编程中采用的最小调度单元是线程束(Warp,即32个Thread),每个Warp只能运行在一个SM上。如果一个SM中包含的SP数量小于32,那么一个Warp的任务就会被分成多个时钟周期来运行。目前CUDA架构的Warp的大小为32,且每个Warp内的线程执行同样的指令,如果同一个Warp内的线程沿不同的分支执行(例如,出现If这样的判断语句时),则会导致部分串行执行,降低程序运行的效率。
GPU中的内存包括寄存器(Registers)、本地内存(Local Memory)、共享内存(Shared Memory)、全局内存(Global Memory)、常量内存(Constant Memory)和纹理内存(Texture Memory)。
每个网格分配一个可被整个GPU线程和外界CPU读写的全局内存,以及可被整个GPU线程和外界CPU读取的常量内存和纹理内存。
每个块分配一个块内所有线程可读写的共享内存。
每个线程分配一个可读写的寄存器和本地内存。
GPU运算是一种典型的单指令多数据的并行计算模式(SIMD),这对于需要同时处理大量并行计算的应用来说有非常大的性能提升。
如前面的介绍,在很多情况下,我们都需要编写使用GPU进行加速的程序,而编写GPU加速程序通常需要安装支持一般并行计算的显卡。目前主流的显卡都是能够支持的,前面我们一直用NVIDIA的CUDA作为示例,其实AMD的显卡也有类似的并行计算功能,AMD并行程序开发采用的是OpenCL。OpenCL是一个开放的并行计算库,有众多厂商支持,这里就不对其做详细的介绍了,因为GPU并行计算的编程原理都是类似的,如果了解了CUDA的编程原理,那么学习OpenCL也会非常容易。
在大多数的GPU并行程序编写中,都会涉及很多算法层面的问题。这里不打算深入并行计算算法的层面,而是主要了解一下GPU并行编程的通用模式是怎样的。下面是一个最简单的并行计算数组加法的CUDA程序。
CUDA编程模型主要是异步的,因此在GPU上进行的运算可以与主机-设备通信重叠。一个典型的CUDA程序包括并行代码及配合的串行代码,串行代码(及任务并行代码)在主机CPU上执行,而并行代码在GPU上执行。主机代码按照标准的C语言进行编写,而设备代码使用CUDA进行编写。我们可以将所有的代码统一放在一个源文件中,也可以使用多个源文件来构建应用程序和库。
一个典型的CUDA程序实现流程遵循以下步骤。
(1)把数据从主机端内存拷贝到设备端内存。
(2)调用核函数(Kernel)对存储在设备端内存中的数据进行操作。
(3)将数据从设备端内存传送到主机端内存。
进行CUDA编程必须知道几个比较重要的概念。
(1)Host:即主机端,通常指CPU端(可以采用标准C语言编程)。
(2)Device:即设备端,通常指GPU端(数据可并行,采用标准C的CUDA扩展语言编程)。Host和Device拥有各自的存储器。CUDA编程包括两部分,一部分是主机端代码,另一部分是数据并行执行的设备端代码。
(3)Kernel:又称为核函数,它是在GPU端执行的数据并行处理函数,由于Kernel函数算法和设计的不同,在性能上会有很大的差别,因此只有设计出最优化的GPU核函数,才能充分利用GPU的资源。
1.FPGA
现场可编程逻辑门阵列(Field-Programmable Gate Array,FPGA)是一种特殊的可编程定制的集成电路。FPGA可通过编程来定制特定的数字集成电路功能模块,使用硬件描述语言(HDL)改变芯片内电路的连接,从而形成特定功能的集成电路。电路图设计曾经是硬件设计的主流方式,但是随着电子设计自动化(Electronic Design Automation,EDA)工具的普及,用电路图设计硬件的情况变得越来越少,如今只有在模拟电路的设计中还经常会采用电路图设计的方法。当然,模拟芯片的设计也需要用到特定的EDA工具,不过这已经超出了本书的范围。
一个典型的数字芯片是由大量的逻辑门电路连接成的,提供特定运算和处理功能的集成电路。我们进行FPGA或ASIC设计,就是根据需要实现的功能,通过硬件描述语言将芯片功能设计出来,然后通过仿真器模拟和测试芯片的功能,最后将测试通过的代码输入综合器,将程序编译烧录到FPGA中,形成特定的功能模块。ASIC则必须通过代工厂流片,形成固定功能的集成电路芯片。FPGA本身的可编程性及内置的大量可编程逻辑块,赋予了FPGA非常高的灵活性和较强的并行处理能力。我们可以通过对FPGA芯片进行编程,生成专门高效处理某一类大规模并行计算的硬件结构,可以极大地加快算法的运行速度。
对于边缘计算来说,FPGA的灵活性和高效并行使得这种技术能够在很多边缘计算的场景中使用。例如,在现场进行深度学习模型的推理和计算;并行处理大量的实时工业数据;实时分析视频和时序数据等场景。而且由于FPGA的特点,在很多特定的小众边缘计算领域中,需要进行定制的硬件加速,但是大批量定制芯片又不经济的场合,非常适合使用FPGA。FPGA本身支持多种输入/输出接口,可以适配各种边缘设备的接口。
下面我们来看一下FPGA的硬件组成,FPGA中最多也是最重要的组成部分就是通用逻辑块(CLB)了,一个逻辑块通常由查找表(Look Up Table,LUT)、寄存器、选择信号线和进位信号线等部分组成。一个三输入的LUT就可以形成一个8位二进制数输入和单输出的逻辑单元,通过查询查找表,获得逻辑的输出值。一个FPGA芯片由成千上万的逻辑块构成,这些逻辑块都通过不同层级的内部线路相连接。通过改变逻辑、时钟信号和选择信号,可以形成不同的逻辑功能。大多数LUT实现其实是一个RAM电路,用于存储逻辑值,比如三个二进制数A、B和C的逻辑与计算可以通过表2-1所示的查找表实现。不同规格的FPGA包含了几万个逻辑块到几千万个逻辑块不等,高端的FPGA执行速度和集成度都非常高,可以实现非常复杂的逻辑功能,而且还拥有非常高的性能。
表2-1 LUT实现逻辑电路功能
除大量的逻辑块外,现代FPGA还有其他组成部分。可编程输入/输出单元(IOB,简称I/O单元)也是FPGA非常重要的组成部分,其单元电路如图2-8所示。IOB是芯片与外界电路的接口部分,可以实现不同电气特性下对输入/输出信号的驱动与匹配要求。FPGA的IOB通常按组(bank)分类,每个bank都能够独立地支持不同的I/O标准。每个bank的接口标准由其接口电压VCCO决定,一个bank只能有一种VCCO,但不同bank的VCCO可以不同。只有相同电气标准的端口才能连接在一起,VCCO电压相同是接口标准的基本条件。通过软件的灵活配置,可适配不同的电气标准与物理特性,可以调整驱动电流的大小,还可以改变上、下拉电阻。目前I/O口能够支持的频率也越来越高,某些高端的FPGA通过DDR寄存器技术,可以支持高达2Gb/s的数据传输速率。
图2-8 FPGA的IOB
配合FPGA功能的实现,还有其他的一些通用模块,具体如下。
(1)数字时钟管理模块DCM。这个模块提供全局时钟的管理功能。DCM的功能包括消除时钟的时延、频率的合成、时钟相位的调整等。DCM可以实现零时钟偏移(Skew)、消除时钟分配延迟,并实现时钟的闭环控制。另外,FPGA的时钟可以映射到电路板上,用于同步其他的外部芯片,可以将芯片内外的时钟控制一体化,以便于系统统一设计。对于DCM模块来说,其关键参数为输入时钟频率范围、输出时钟频率范围、输入/输出时钟允许抖动范围等。
(2)嵌入式块RAM。大多数FPGA都具有内嵌的块RAM,这大大拓展了FPGA的应用范围和灵活性。块RAM可被配置为单端口RAM、双端口RAM、内容地址存储器(CAM)及FIFO等常用存储结构。CAM在其内部的每个存储单元中都有一个比较逻辑,写入CAM中的数据会和内部的每一个数据进行比较,并返回与端口数据相同的所有数据的地址,因而在路由的地址交换器中被广泛地应用。除了块RAM,还可以将FPGA中的LUT灵活地配置成RAM、ROM和FIFO等结构。在实际的应用中,芯片内部块RAM的数量也是选择芯片的一个重要考虑因素。
单片块RAM的容量为18kbit,即位宽为18bit、深度为1024,可以根据需要改变其位宽和深度,但要满足两个原则:首先,修改后的容量(位宽×深度)不能大于18kbit;其次,位宽最大不能超过36bit。当然,可以将多片块RAM级联起来形成更大的RAM,此时只受限于芯片内部块RAM的数量,而不再受上面两个原则的约束。
(3)内嵌专用硬核/软核。IP(Intelligent Property)核是具有知识产权的集成电路芯核总称,是经过反复验证的、具有特定功能的宏模块,与芯片制造工艺无关,可以移植到不同的半导体工艺中。目前,在很多FPGA芯片中都包含了预先成型的CPU内核、数字信号处理器(DSP)模块及高速乘法器等IP核。这些核可以通过FPGA程序方式提供,也有一些是直接内嵌在芯片中提供的。某些混合型的FPGA甚至还带有数模转换和模数转换模块,用于处理模拟量的数据。
如今的FPGA已经向可编程SoC的方向发展,在芯片中加入了嵌入式CPU内核和各种外围的模块和接口。图2-9所示的Xilinx Zynq-7000中内置了1GHz主频的ARM双核Cortex-A9 MPCore CPU核心,以及各种外围的输入/输出模块。
图2-9 Xilinx Zynq-7000可编程SoC
目前FPGA市场占有率最高的两大公司Xilinx和Intel生产的FPGA产品大多是基于静态随机存取存储器(SRAM)工艺的,需要在使用时外接一个片外存储器以长期保存程序。上电的同时,FPGA将外部存储器的数据流写入FPGA的RAM;断电后,RAM数据清除,内部逻辑也同时失去。Actel、QuickLogic等公司可以生产基于反熔丝技术的FPGA,程序只能够烧录一次,这类产品使用成本较高,开发和验证也比较麻烦,但是具有抗辐射、耐高低温、低功耗和速度快等优点。因此,基于反熔丝技术的FPGA通常用于军工、航天等对耐久性、可靠性和性能要求都比较高的场景。
Xilinx最近紧跟AI技术和边缘技术的发展,推出了Versal系列解决方案。Versal AI Edge ACAP (架构如图2-10所示)是面向边缘计算的计算加速芯片解决方案,已在2022年9月批量供货。ACAP是指自适应计算加速平台,可以适应和加速不同需求的计算和应用。在Versal AI Edge ACAP的介绍文档中提到,Versal AI Edge系列采用了7nm Versal架构,并针对低时延AI计算进行低功耗设计,其功耗水平低至20W,并且符合边缘应用中的安全与保密要求。作为一款搭载多样化处理器的异构平台, Versal AI Edge系列能够采用多种计算内核,以匹配不同的机器学习算法。
Versal AI Edge采用了以Arm Cortex-A72和Arm Cortex-R5F作为内核的标量引擎(Scalar Engines),支持通用型的计算任务,通过自适应引擎(Adaptable Engines)支持传感器融合和灵活的并行硬件编程,通过智能引擎(Intelligent Engines)支持人工智能训练和推理。其最高的计算吞吐性能高达17.4TOPS,是上一代产品Zynq UltraScale+的4倍。同时,其单位性能功耗只有GPU的四分之一,能够支持视觉、雷达、激光雷达(LiDAR)及软件定义的无线连接等信号处理工作。
图2-10 Xilinx Versal AI Edge架构
2.ASIC
ASIC是将通用的定制芯片作为特定场景和需求设计生产的芯片,通常也是采用FPGA的设计方式,用FPGA进行验证和试用。当设计的芯片功能和性能达到设计要求后,将整个EDA设计文件编译生成后交给芯片代工企业进行生产和加工,形成固定的专用功能芯片产品。目前的各类人工智能芯片及专用的加速芯片都是先用FPGA验证,然后形成ASIC产品。ASIC由于其专用性,在批量生产时与通用集成电路相比,具有体积更小、功耗更低、可靠性提高、性能提高、保密性增强、成本降低等优点。
放眼未来,有不少新兴的计算硬件技术的发展值得我们关注,这些技术的研发、成熟和应用,会对物联网和边缘计算技术产生非常重大的影响。
1.存算一体化技术
对于未来计算机和人工智能发展的存储墙和算力墙该如何破解,不同的学者和工程师给出了不同的答案。目前来看,存算一体化技术似乎是最有希望取得突破性进展的领域。下面我们来看看什么是存算一体化技术。
目前人工智能是非常重要的发展方向,但是深度学习所需的计算量比以前的传统计算机应用的计算量呈几何级数增加。为此,各国的研究机构建造了巨型数据中心和超级计算机。我国的神威·太湖之光超级计算机可以达到93PetaFLOPS的浮点数计算能力,但是消耗的能量也达到了15371Megawatts,基本上可以供应一个小型城市的用电量。为了减少对集中式的数据中心和超级计算机的依赖,我们希望能够在边缘端的采集设备和存储设备上进行数据处理,从而分流掉计算中心的计算压力。
边缘计算技术天生地可以利用到存算一体化技术,我们可以将数据源头采集到的数据存储到边缘服务器,并在内存中即时进行数据计算和处理。边缘计算就是一种分布式的数据处理拓扑架构,能够在靠近数据源头处完成全部或部分的数据运算和处理。数据收集、处理和存储尽量靠近,可以大大节省通信带宽,同时还可以大大减轻对于云数据中心的存储和计算压力。对于机器学习场景,在边缘端的训练还可以提供在中心服务器端训练无法完成的功能。例如,实时训练模型,以实时适应现场状况的变化。
对于当今的机器学习,尤其是深度学习的训练和推理,往往都需要做大量的向量矩阵乘法(Vector-Matrix Multiplication,VMM)计算。根据欧姆定律和霍夫曼定律,这种VMM计算可以非常容易地在存储电路上实现。如图2-11所示,这种电路主要是由模拟存储电路加上可变电导G构成。在每个内存节点都会有一个这样的可变电导,整体会形成一个模拟生物突触的神经网络,这样的结构可以通过本地存储的数据和电导的变换进行VMM计算。
图2-11 电阻性存算一体化芯片的原理
存算一体相对于目前的冯·诺依曼这种将存储和计算分开的体系来说是一种颠覆性的创新,也更加符合人类大脑处理数据的方式。在传统的计算机架构中,数据存储和计算是被割裂的,而数据的移动在很多应用中往往占用了大量运行时间和计算能力,同时在大规模计算领域中,内存到计算单元的带宽往往成为整个计算机系统的瓶颈。存算一体可以非常好地解决数据搬运造成的问题,而且能够降低计算机系统的整体功耗。
2.全光学和电光混合芯片技术
光子器件具有超大带宽和低功耗的特点,而且光具有高达100THz的超高频和多量子态自由度,使得光子计算成为超大容量、低延迟矩阵信息处理中最具潜力的候选技术方向之一。虽然目前光电计算芯片技术还不成熟,但是各国研究机构和企业都投入大量资金进行研发。近年来,光子矩阵乘法技术发展非常迅速,广泛应用于光信号处理、人工智能、光子神经网络等光子加速领域。这些基于矩阵乘法的应用显示了光子加速器的巨大潜力和机遇。
光子矩阵矢量乘法(MVM)的方法主要分为三类:平面光转换(PLC)方法、马赫-曾德干涉仪(MZI)方法和波分复用(WDM)方法。
光子矩阵乘法网络本身可以用作光子信号处理的通用线性光子回路。近年来,MVM已发展成为各种光子信号处理方法的强大工具。
人工智能技术已广泛应用于各种行业,例如,基于深度学习的语音识别和图像处理。MVM作为人工神经网络(ANN)的基本构建块,可以承担大部分矩阵计算任务。提高MVM性能是ANN加速最有效的手段之一。与传统电子计算相比,光子计算在数据存储和流量控制方面的能力较差,并且光学非线性的低效率限制了其在非线性计算中的应用。由于深度学习中的激活函数都是非线性函数,因此光子矩阵如果用于深度学习的训练和推理,需要结合其他的非线性电子技术。光子计算与人工智能的结合,有望实现智能光子处理器和光子加速器。光子计算在信号速率、延迟、功耗和计算密度方面具有明显优势,不过目前的精度普遍低于电子计算。
在全光人工神经网络成熟之前,特别是在光学非线性效应和全光级联成熟前,光电混合人工智能计算仍是一种更实用、更有竞争力的深度人工神经网络的候选架构。因此,开发高效、专用的光电混合人工智能硬件芯片系统是光子人工智能的核心研究路径之一。