第 1 部分:基础知识
硬件电路设计的基础概念 | 集成电路基本概念
在我们实验室的主要工作是数字设计,也即将某些算法映射成专用的数字电路来进行加速优化。通过模拟电路进行算法加速暂时不属于我们实验室的主要工作。
简单说一下关于模拟电路进行算法加速的优点与缺陷:
- 优点:
- 计算功耗低
-
占用硬件资源(晶体管数)和面积小
-
缺陷:
- 大部分信号处理系统都是数字的。即使用模拟电路进行算法加速,最终将模拟信号转换为数字信号需要ADC,然而ADC面积大功耗高。
- 另外,模拟电路对噪声的鲁棒性比较差,会有失真,只适合一些对噪声不敏感的算法
我们实验室通常进行算法硬件加速的一般步骤
-
算法的软件实现、分析算法性能,找出算法的瓶颈。
-
对算法的瓶颈部分(比如CNN中的卷积计算)的计算特点等进行面向硬件实现的优化,优化的方向主要是:
- 高速
- 低功耗
- 小面积
确定优化目标,比如想要达到多少吞吐率之类的。
-
根据优化后的算法设计和优化硬件架构(Hardware Architecture, 包括数据通路、数据流和控制)。
-
两个术语: Architecture、Micro-Architecture。一般的设计都从这两个方面进行设计。前者是一个比较大的范畴,比如这个专用硬件需要有哪些模块,每个模块之间怎么交换数据。后者是对前者的精细化实现,比如某个模块中的加法器是使用Carry-Ripple 加法器还是Carry-Look-ahead加法器。另一个例子就是Intel的CPU和AMD的CPU都用的x86的指令集,因为他们的Instruction Set Architecture是相同的,但是这些指令集具体如何实现(Implementation,比如某种指令花费多少个时钟周期),各家就不同了。
-
算法数据的量化: 一般算法在计算机上都是浮点数表示,每个浮点数32bit,很多算法的精度需求并不需要那么多bit来表示数据,如果一个专用硬件还用32bit就会太亏了。另外,浮点计算单元也很复杂,所以算法的硬件实现时我们尽量使用比较小的位宽(data width)的定点计算单元。
-
为了达到这一目的,需要将a)中的软件实现转换成定点数计算,并研究对算法性能的影响。目标是使用尽可能低的精度而不会有多少性能损失(如分类精度减少0.01%以内)。
-
建立一个该硬件架构的软件模型(如通过C/Python等模拟该架构的计算流程、量化方式等,至于建模的精度就看需求了,可以是cycle-accurate的也可以只是模拟一下整个模型数据的交互,越精确实现起来越麻烦,但对硬件实现带来的指导就越多),该架构的软件模型需要在本质上和a)中算的的确是同一个东西。这个软件模型就会被当作验证你的硬件架构实现正确与否的参照。硬件架构最终的实现必须与该软件模型完全相同。
-
另外,这个硬件架构的软件模型也尽量可以写成参数化的。比如并行度是一个参数N,那么在真正硬件实现之前就可以用这个软件模型通过改变N进行Design Space Exploration。因为真正在使用硬件描述语言进行实现后要进行更改会比在这个层次进行更改麻烦很多。可以通过在这个层次选择得到一个比较好的N之后再实现,得到更优的效果,或者是如果你做得这个工作目标是想达到什么速度、精度指标,如果能在这个阶段提早知道就事半功倍。
-
当然,如果你对自己的design足够有信心没有任何差错或者只是想实现一个,不在乎是不是最优的,也可以跳过这个e)直接做f)。
-
使用Verilog等硬件描述语言(HDL)对e)中的模型进行RTL级的描述实现、仿真验证。 这一步骤中实现的东西需要和e)中的输出结果等方面完全相同。另外,要注意的是这一步骤的重点是描述,因为各个模块的连接方式什么的实际上都已经有了,这部分工作主要照着之前设计的架构进行各个模块的例化、连线,而已经不属于设计了。所以在写这部分代码的时候,每一行代码在你心中都要有对应的电路,要保证写出来的代码都是能综合出对应的电路。
-
一般来说在这个步骤中的每个层次的模块都分两步进行描述:
- 实现/验证数据通路
- 实现/验证该数据通路的控制逻辑(一般是通过实现一个状态机)
根据经验,两者花费的时间比例基本上是2-8或者3-7。
-
将上述Verilog代码进行综合(Synthesize)实现,也就是把他们真正映射成你设计的电路的门级网表(gate-level netlist)。再对该门级网表进行功耗分析。
-
阅读综合实现的报告,比如能达到多少频率、面积有多大、功耗多少等等。看看在b)中设计的指标是否达到。若没有达到,可以考虑:
- 改变综合选项重新综合
- 分析没达到指标的原因并返回c)d)e)f)对该部分再次优化(当然如果是小改动直接改RTL也可以,只要能保证功能没有错误)
如果达到指标要求了,基本上一个数字集成电路前端设计流程就结束了。我们实验室大部分工作都到这一步骤就OK。
-
如果是想进行FPGA实现,那么在这一步也是综合生成netlist和看报告。但后续还可以实际下板子(毕竟不像ASIC要流片成本……),从而得到非常真实的结果。
-
在集成电路或ASIC设计的实际流程中,前端设计完毕后还有后端设计,比如版图设计(Layout)、布局布线(Place & Route)、后仿真、形式验证、静态时序分析等等。但是那些太费时间了,一般的科研中最多再做个版图、布局布线和基于后端结果的功耗分析就OK了。反正越往后的结果越准确,但是工作量也越大。
面向硬件实现的优化方法简单举例
- 优化目标: 高速(high speed)、低功耗(low power)、小面积(small area)。
- 优化层次: Algorithmic Level、Architectural –Level、Circuit Level。优化层次越高收益越高。如果你在算法上就比别人优越了33%,别人在架构上怎么优化也不会比你好的。
- 指导思想: 人没有牺牲的话就什么也得不到,为了得到某些东西就必须付出同等的代价。总之,优化就是牺牲某些你并不太care的性能换取你想要的性能(Engineering is tradeoff),永远不要又想马儿跑又想马儿不吃草。
Algorithmic Level优化举例:
-
减少面积: 比如乘法器在硬件上的复杂度是O(n²),而加法器的复杂度是O(n),此处n可以认为是数据位宽,也即一个乘法器的面积可能达到一个加法器的数十倍。那么,通过一些算法变换减少乘法数目就可以显著减少面积。再比如某些数据并不需要存在芯片中,如果可以动态生成,那么就可以减少可观的面积。设计能够动态生成这些数据的算法。
-
高速: 一个硬件电路的计算速度主要被工作频率、计算并行度所制约。
- 工作频率有个上限,也即电路中组合逻辑的最长延时的倒数。在算法上可以根据观察计算表达式等方法知道如果直接用乘法器、加法器等单元实现他们会有多长的组合逻辑(比如N个加法器和M个乘法器),那么就可以考虑例如改变某些计算顺序、循环展开再优化、用更多加法换取乘法的减少等方法来降低组合逻辑上的延时。这样就可以提高工作频率。
-
计算并行度一般来说只要不超过整个算法的总计算量,是可以任意增加的。但也要考虑有可能提高了计算并行度之后会降低系统频率。所以提高并行度并非总是可行。而且提高并行度的代价是面积变大,这些都要考虑到。
-
根据算法特性,针对计算量减少的优化
-
低功耗: 事实上一般高速和低功耗是一对双生子,某些方法可以让电路变得高速(如缩短关键路径来提高频率),那么这些方法一般来说也可以降低功耗。
Architectural/Micro-Architectural Level优化举例:
- 不同的数据的访问成本、不同存储器的面积成本是不一样的,不同的存储器访问功耗也不同。比如在Memory Access Power上:DRAM(200)>>SRAM(6)>Register(1)。
- 而在面积效率上:Register > SRAM > DRAM。
- 所以具体哪种数据存在什么存储器上要读取几次的设计就需要进行一番考虑。
Circuits Level优化举例:
- 一般就是比如使用新型存储器、新型器件,采用DVFS方式之类的,不太了解不过多介绍。
优化总结:
- 很多优化都是Application Specific的,要通过多看文章积累。General的优化方法看看Parhi的书就差不多了。
编程语言
在我们实验室主要需要做的工作是利用软件仿真算法,并在算法的基础上进行硬件的优化和实现。那么在这个过程中,不可避免的需要利用编程语言来实现软件/硬件上的功能,一般需要用的语言如下所列:
- C/C++: C语言应该说是基础中的基础,几乎所有的深度学习开源平台都是用C++来实现。
- Python: 几乎所有的开源框架上层都是用python封装起来。
- Verilog: 硬件设计过程中也需要用Verilog来实现你设计的架构。切记不可用软件的思维来写verilog。
- Matlab: matlab也非常的易用,大致和python差不多容易用。
- CUDA: 现在我们用的nvidia的GPU都是用cuda进行编写。
深度学习开源平台简介
在深度学习方向。大家不要把系统/算法从头搭起,目前的众多开源框架已经完全可以满足我们的需求。下面列的几个实验室的基本都用人用,大概的介绍如下:
- Caffe: Caffe 有非常好的特性,但也有一些小缺点。
- Tensorflow: tensorflow是谷歌的产品,文档相当相当的丰富。
- Theano: Theano 是最老牌和最稳定的库之一。
- Torch/Pytorch: 这也是一个很著名的库。其最大的优势是,安装和使用起来实在是太方便了。
这部分内容为后续的硬件设计和优化奠定了理论基础。建议结合实际项目进行深入学习。