在2020年北京召开的亚太地区设计自动化会议上,中国工程院美国工程院双院院士丛京生教授发表了关于可定制计算的主旨演讲。
众所周知,我的主要研究方向是电子设计自动化(EDA)。我在这个方向上的研究可以分为两个阶段:
在2009年之前,我比较注重于面向硬件设计人员的电子设计自动化。但是在过去的十年,我在面向软件工程师的电子设计自动化上做了大量的工作。
这是因为我认为可定制计算(Customizable Computing)将会是未来芯片应用上的大势所趋,我的研究方向逐渐开始转向为众多的软件程序员提供设计自动化来使用或生产可定制芯片。
2008年,我们向美国国家科学基金会(NSF)递交了一份提案。在提案中我们提出可定制计算将会是计算行业的未来,特别是在大家已经对各种各样的并行计算做到极致之后。
我们说并行计算当然非常重要,但是再往下走一步就是可定制计算的天下,因为可定制计算可以根据具体任务计算量的不同去选择合适的计算架构。
很有幸NSF方面同意资助我们的探索计划。在这之后我们在这个方向上做了很多的工作。
可定制计算和人们通常所知的通用处理器相比有着巨大优势。
实际我在UCLA的同事Ingrid Verbauwhede教授的工作对我们的研究有不少启发。她2003年在加密编码算法的研究中得到了对于可定制计算非常有利的实验结果[6]。
她使用加密算法的专用集成电路(ASIC)实现作为性能基数,如下图左边表格第一行所示。第二行是使用可定制计算的方法得到的运行数据,第三行是在ARM上编写汇编得出的运行数据。
可以看见,可定制计算总体优于此种方式85倍。
再往下一行是在奔腾CPU上编写相同功能的汇编代码得到的运行数据,这在当时是最好的台式机芯片。可定制计算的优势高达8000倍。
也许你会说这项研究是否有点老?那我们再来看一些其它的比较工作。
右侧的图表来自一篇斯坦福大学2010年发表的文章[7]。他们使用H.264视频编解码算法对定制指令集进行了评估。可以看见,即使是用上了SIMD和定制指令集,通用CPU和ASIC的差距还是有50倍。
显然你不可能对每个计算应用都开发专门的ASIC,这是一项既烧钱又耗时的工作。关键问题是任何算法的改动都需要重新开发一整块新的ASIC。
请注意在左边的例子中,第二行的可定制计算是使用可重构的现场可编程逻辑门阵列(FPGA)做的实现。它既可以做到快速低成本,又保证高于通用CPU的性能。所以利用FPGA是一个非常有前景的解决方案。
我们的解决方法很简单:知道了CPU在这方面的不足,那我们就把关键的计算任务交给可定制计算加速器[8]。这样的架构就和以前的单一机器或者单一芯片的计算架构不一样。
为什么这是合理的呢?如果你仅有有限的计算资源,通用计算架构是一种非常好的做法。
我可以问问大家,第一台计算机里有多少真空管,或者第一块集成电路上有多少晶体管?
其实这个数字不是很多,ENIAC大约有6万个真空管,第一块微处理器更少,只有2200来个晶体管。
就这么点资源,你没有办法同时执行所有指令。唯一的办法就是走一条流水线然后复用资源——这是那个年代的限制。
当今我们的限制不一样了,你口袋里的手机里就有十亿量级以上的晶体管。但你不能让所有的晶体管都运转起来,不然手机的电池很快就撑不住了。所以当代的限制从资源的限制变成了功耗的限制。
打个比方,一个三人的公司可能不太需要定制化,因为每个员工都非常了解另外两个员工做的事情并会帮忙解决。但是像微软这样有几万员工的大公司,就需要定制化精细化分工。
我们的社会就是一个定制化的社会,不同的人做着不同的职业。你生病了不会去找律师,一定是去找医生。找医生时一定是去找了解你疾病的专门科室的医生。
我们的大脑有1千亿个类似晶体管的结构,这些神经元也是有具体分工的。我问了很多神经学专家,他们之中没有人告诉我大脑里有流水线。大脑不同部分的神经元有着不同的功能,有的管说话,有的管认字。我把大脑里这些不同的模块也叫做加速器。
可定制计算的做法有两种。富人有富人的做法,穷人有穷人的做法。
像Google这样的巨头可以为机器学习设计专门的TPU。TPU可能是AI应用中第一块专门的ASIC,这是一个非常了不起的成就。和通用CPU相比,TPU可以达到100倍以上的性能提升。
但试问有多少公司能像Google一样做出巨额投资并且等上18个月来换取一块TPU?我个人认为Google的做法并不是一个普适方案。
我对于第二种低成本的做法抱有更大的兴趣。
这种做法就是利用FPGA来替代专用芯片。我在提交给NSF的提案中就使用这种做法。
我相信很多人在学校里都学过或者用过FPGA。现在的FPGA已经方便到你可以把FPGA的开发板插进你的电脑主板上直接使用。FPGA的关键所在就是它的逻辑单元(Logic Block)可以实现任何k-输入布尔表达式。
实现这个功能听起来很玄但其实很简单。k-输入布尔表达式有2^k大小的真值表。放2^k个SRAM来存真值表的每个值就可以了。当然,别忘了放一些可编程的逻辑互联模块,把所有的逻辑单元连起来。
FPGA有多种不同的方式与服务器进行连接[9]。最简单的方式是将单块FPGA直接插在PCI-E上,也有将多块FPGA连在总线上的方法,有HARP这种考虑到内存一致性的插板方式,Intel的FPGA则是可以放在QPI总线上。
总的来说,把FPGA和通用CPU连在一起工作并不是一件很难的事情。在UCLA我们很早就已经把FPGA放进了计算集群(Cluster)里。
微软是在数据中心使用FPGA的领航者。早在2014年他们就把FPGA插进了服务器并且用于Bing的搜索服务。之后微软的架构可以将所有的FPGA连到同一块交换机,并且再和上层交换机进行交互。这样使海量FPGA执行大规模的AI计算成为了可能。
亚马逊的AWS现在也有了F1专门为FPGA加速提供服务。我在UCLA教课时就要求学生使用亚马逊F1来完成他们的FPGA加速作业。
我们可以看到,把FPGA放进当下各种规模的计算机系统已经不成问题。
那对于一个开发人员来说剩下的问题在哪呢?我觉得最大的问题在于:有这么一个超强的计算器件,你可以利用它得到非常好的结果,但是你不知道怎么去编程来驾驭这个怪物。
特别是FPGA这样的异构计算器件,对于一个软件工程师而言完全是陌生的。
大约在15年前,我们开始了一项新的工作叫做高层次综合(High-Level Synthesis,HLS)[10]。
软件工程师可能没有办法直接设计硬件电路,但是他们会写C代码。我们的工作可以帮助他们将C代码自动转换成对应的电路描述。
这项工作我认为我们做的比较成功。当时LLVM编译架构刚刚问世不久,我们觉得它有很好的中间表示,于是立刻在它上面进行开发。
用户的代码经过LLVM-IR优化之后直接通过我们自己拓展的后端生成硬件描述。我们将这项工作成功转化成了商业产品AutoPilot,并在2006年成立了AutoESL公司。
在2011年, 赛灵思(Xilinx)收购了AutoESL,并把AutoPilot改名成为了大家熟知的Vivado HLS。也许你们中的一些人用过Xilinx Vivado HLS,这其实是一项从UCLA开始,并从AutoESL成长起来的产品。
赛灵思在收购AutoESL之前对我们的高层次综合工具做了大量评估。他们通过对比大量已有的手工设计来检验高层次综合是否能得到令人信服的结果。
实际评估后赛灵思发现我们的高层次综合工具做出来的结果在维持最优的时钟周期的同时,还可以有更低的资源消耗。
高层次综合是电子设计自动化的一项非常令人激动的进步,因为它使得从C语言到硬件电路成为了可能。
赛灵思在收购我们的工具之后也维护的很好。现在我的课上学生可以选择使用HLS来设计电路,学生们的反馈也很好。在Google搜索”Vivado HLS”的科研文章可以搜到超过4000篇。它在工业界有着数以万计的用户。
以上对于高层次综合来说是很好的消息,但是不好的消息是光靠高层次综合其实是不够的。
为什么这么说呢?这里有两个问题。
第一个问题是CPU和FPGA之间程序抽象的区别越来越大了。用高层次综合当然可以从简单的C/C 变成电路,但是从下图我们可以看见软件标准和发展的曲线正在变得越来越陡峭。新兴的特定域计算语言,比如人工智能的语言,正在快速进化和发展。
第二个问题在于,实现相同功能但使用不同写法和风格的C/C 程序,通过高层次综合会跑出不同结果。有的结果甚至大相径庭,以至于比CPU的结果还要差。
所以写出好的HLS C/C 代码,是要受过训练的。我实验室的学生在学习的第一年,很少有人能写出比CPU跑的还好的HLS C/C 代码。
在这里我想举一个例子,我的两位研究生在学习的第一年,针对生物信息学的Needleman-Wunsch序列匹配算法进行加速。
当他们写完程序之后,发现高层次综合两分钟就给了他们对应的电路设计,他们非常开心。但是实测发现,他们的设计性能比CPU慢了100倍。
如果我们仔细看这个电路到底发生了什么,我们就会发现:
1)输入每次只读了8比特, 而FPGA的总线宽度有512比特。
2)这个电路没有做缓存,所以每次输入都是从片外存储器读进来的,这样的延时很高。
3)所有的循环是顺序执行。
4)所有的计算逻辑都在读写相同的片上数据,而FPGA的每个片上存储单元只有两个端口。同一时钟周期内存储单元每次只能接受两个数据访问请求,得不到数据的计算逻辑需要等待。这是影响性能的最大瓶颈。
所以这样的高层次综合设计是不可能好于CPU的性能的。
但当他们受过一年训练之后,就知道怎么利用编译指令(pragma)来控制各种粗细粒度的流水和并行,怎么把数组进行分块等等。这样的设计结果就会远远好于使用通用CPU。
然而还有一个问题是,最后性能优化的HLS C/C 代码可能会很长,甚至和原始代码相比面目全非。
类似这样对于一个软件程序员进行常年的HLS C/C 代码的训练,并不是可推广和有效率的模式。
我的希望是,在座的各位只要经过一些基本优化理论的训练,就可以通过写软件代码得到优于通用CPU的设计。这样大家才能广泛体会到可定制计算能够带来的好处。
不恰当地说,我想“民主化”可定制计算这项技术——使得它可以被所有人轻松的使用,而不再是掌握在少数人手里的垄断技术。
大家可以看到我们的科研计划,我们真心实意地想在高层次语言和电路实现中间构建起一座桥梁。
我们从C /C , Caffe/Tensorflow, Spark, Halide等语言和框架出发,把他们变成通用的中间表示,然后再把他们映射到各种各样高性能的微架构上去。
这些步骤我们希望都是自动的、智能的,不需要用户干预。
我的学生们已经在使用峰科计算(Falcon Computing Solutions)推出的Merlin编译器,通过几十分钟的训练,就可以得到和经过几年高层次综合训练的学生相同性能的设计。
在这里,我举一个我们已经实现的微架构优化的例子,将某些计算模块映射到脉动阵列(Systolic Array)上。
这是一个已经提出很多年的结构,一个单元只能和它的邻接单元通信,其目的就是减少各个计算单元之间的通信损耗从而提高运行频率。
这里的第一个问题是什么样的应用可以映射到脉动阵列。第二个问题是通过什么方式可以从众多不同参数的脉动阵列解法中找出一个最优解。
这两个问题都不容易。我们为此开发了一个PolySA 编译器来专门解决这个问题[11]。
在这里我不具体展开,简单来说我们把其中的多重循环转化成多边形模型(Polyhedral Model)来求解。
从这个模型出发我们发现了一条可以映射到脉动阵列的路。通过PolySA,我们发现对于矩阵乘法有五种脉动阵列的结构存在潜在的最优解,对于卷积神经网络(CNN)则有15种潜在的脉动阵列结构[12][13][14]。
另外一个微架构例子是模板计算(Stencil Computation)。
比如在下图中某一像素的值将会根据相邻四个像素的值进行更新。借此技术,图片可以做模糊或者锐化的操作。
假设我们要在一个时钟周期内完成计算所需要的数据访问,鉴于存储器的端口有限,相关的五个数据元素最好能从五个不同的存储体(memory bank)中同时得到。
更复杂一点,如果我想同时处理多个像素点,我需要保证更多的数据来自于不同的存储体。所以这个计算任务不管是片内还是片外,存储访问都是瓶颈。
我们设计了一个可定制的存储架构来满足以上需求[15]。这个架构里有一系列的FIFO,算法根据数据访问模式自动设计这些FIFO的长度和推入推出行为,从而保证每一时钟周期下所需数据都按时取得。
我们研究的一个更加通用的架构叫作可定制并行流水结构(Customizable, Parallel, and Pipeline (CPP) Architecture)[16]。
FPGA有数以百万计的逻辑门,在这个资源范围内,有两件事情你可以做的非常好。
第一件就是大规模的并行化电路执行,想多并行就多并行。第二件就是任意长度的流水线,想多长就可以有多长。
我们AutoESL的第一个客户其实并不是来自半导体行业,而是金融行业。
他们跑来问我能不能试用我们的产品。我问你们想用我们的产品做什么?他们说做高频交易——用可定制的电路只要比别的公司用CPU做的快一秒就能挣非常多的钱。
他们给我们的第一个测试案例是金融界知名的Black-Scholes模型。我们的实现用了300多级流水线实现了令他们非常满意的结果。
不仅仅是流水线,通过我们的研究发现,一般的高层次综合加速任务只要照着我们的优化模板来做,就能达到很好的效果。
首先你需要做存储访问和计算的拆分。接着尽量做宽内存访问(Memory Coalescing)来达到最大的带宽使用率。然后小心地设计片上存储分块,保证计算需要的并行片上数据访问。最后确保所有的循环都可以被并行执行或者按流水线执行。
实现上述步骤还是需要一些专业训练。 我们现在提供了Merlin编译器,来自动地按照这个流程进行计算加速优化。我在2014年成立了峰科计算来给业界提供这样的解决方案。 我们希望Merlin编译器可以为CPU FPGA的可定制计算提供更大的便利。Merlin编译器给用户提供了及其简单的pragma来进行优化操作。用户可以简单地指定哪里需要做流水线,哪里需要做并行。 这样的操作极大地简化了HLS的难度。相比于HLS的设计, Merlin现在可以减少90%的pragma数量,达到相同的最优性能。这样利用C/C 做电路设计的难度就大大减小了。
不过我们觉得这样还不够。利用Merlin设计时用户还是需要一些经验去指定哪里应该做流水线或者并行。
有没有什么方法能够让机器自动找出最优解呢?我们现在正在基于Merlin结合人工智能算法进行各种各样的尝试。
有一天,我和我的学生说现在人工智能已经能打败最厉害的围棋选手了,也许我们的工作以后能打败最有经验的硬件设计师。
这件事情比围棋的人工智能设计困难很多。因为围棋的规则是确定的,即使解空间很大但只要是确定规则,理论上人工智能就可以做的非常好。
而电路设计没有特别定式可寻,所以难度相对比较大。我们在这个课题上已经提出了基于Merlin的解决方案[18],通过学习上一轮设计的性能和缺陷我们可以决定在下一轮中插入什么样的优化。
这套流程已经在我的课上被测试过。
我要求15个研究生首先自己设计HLS C/C 代码得到一个优化的数字识别电路,然后通过Merlin的这套搜索流程来设计相同的电路。
结果区分非常明显:HLS C/C 设计达到的平均性能是18000个时钟周期,而使用Merlin设计的平均性能为 4000个时钟周期,4.5倍的提升。
尽管有一位有几年HLS设计经验的学生仅利用HLS C/C 就得到了3000个时钟周期的最优设计,但可以看出来Merlin的自动设计水平已经非常接近优秀的硬件设计师了。
峰科和UCLA也一起合作在亚马逊AWS平台上评估了很多工业界的测试案例。峰科负责提供Merlin的结果,UCLA负责提供手动设计的结果。我们可以看见全自动的加速结果显著优于通用的CPU结果,而且非常接近手动设计的结果。
最后,我想在可定制计算“民主化”的这条线上补充一下我们最新的科研成果。
我和康奈尔大学的Zhiru Zhang教授一起开发了HeteroCL[19]。这是一个基于Python的硬件加速模型,这项工作为图形图像以及人工智能的高层语言提供了通往FPGA的桥梁。
同时我们也利用了峰科的技术开发了HeteroHalide[21]。Halide语言是麻省理工学院专门为图像处理开发的语言, 而这项工作专门为Halide语言通往FPGA提供了便利。
可定制计算现在已经在各类共有私有云上大面积铺开了。
现在我们的工作致力于消除可定制计算的编程壁垒,使得更多的人能够实实在在利用起可定制计算。
在这条路上我们已经做出了像Merlin编译器、HeteroCL、HeteroHalide等一系列的重大进展,所以我认为这条路的前途是光明的。
我们也欢迎各位专家和学者一起投入到这个领域来,让更加简单智能的可定制计算更好更快地为所有人服务。
谢谢大家。
参考资料:
资料推荐
联系客服