拿到《半导体学报》2020年第2期的样刊时,封面印着“面向高能效人工智能计算的可重构芯片技术专刊”这一行字,说实话我挺感慨的。前几年跟同行聊起可重构计算,大家还觉得是个偏学术的概念,没想到这一期专刊直接把国内这个方向上最有分量的研究团队都聚齐了,从CGRA架构设计、编译映射到流片验证,铺开了一张相当完整的技术版图。
这些年AI算力需求涨得吓人,GPU在大规模并行计算上确实能打,但功耗墙的问题越来越突出。数据中心一块GPU动辄三四百瓦,大规模集群的电费是运营成本里最扎眼的一项。而我长期做芯片架构,一直关注一条更省电的路:可重构芯片。它的思路不复杂——用一堆可配置的处理单元和互连网络,通过运行时改变配置来适配不同计算任务,灵活性向通用处理器看齐,能效向专用ASIC靠拢。听起来很美好,但做起来坑很多,这期专刊恰恰把这些坑和答案都摆到了台面上。
这篇文章我想从自己的实践视角,把这期专刊里最有价值的几条技术线索拆开聊:AI计算为什么会撞功耗墙、可重构架构到底怎么设计、面向AI的能效优化该从哪几个方向下手、以及从论文数字到真实芯片之间还有多长的路。文章最后会附上我自己的入门路径和一些踩坑记录,希望对正打算做这个方向的工程师有点参考价值。
1. 专刊背景与行业痛点:AI计算为什么会撞上功耗墙
1.1 冯·诺依曼瓶颈与数据搬运的隐性成本
先聊一个老生常谈但绕不开的问题。传统芯片基本都遵循冯·诺依曼架构,指令和数据走同一条总线,处理单元和存储器物理分离。这个架构最大的优点是通用灵活,什么任务都能跑,但代价是数据搬运开销极高。AI计算恰好是典型的数据密集型负载:一个卷积层动辄读取几十上百MB的权重和特征图,每次计算都要先从DRAM搬到片上寄存器或缓存里,算完再搬回去。
我做过一个粗略的能耗估算:在28nm工艺下,一次32位浮点乘法大约消耗0.2pJ,而从片外DRAM读取一个32位数据则要消耗大约640pJ。两者差了超过3000倍。换句话说,AI芯片的大部分能耗根本不在“算”上面,而在“搬”上面。这个结论解释了为什么这些年在AI芯片设计里,“减少数据搬运”成了比“提升峰值算力”更重要的事情。这期专刊里至少有三分之一的论文在围绕这一点做文章,方向不同,本质都是一回事:把数据留在离计算单元最近的地方,能复用就复用,能不搬就不搬。
1.2 通用、专用与可重构:三种路线的能效博弈
AI加速这个赛道上,业界基本走三条路。第一条是通用GPU加通用处理器,灵活度最高,什么模型都能跑,但能效不理想,因为指令流的取指、译码、控制开销是刚性的。第二条是专用ASIC,比如谷歌TPU里那套脉动阵列,把卷积的乘累加计算变成固定流水线,能效可以做到GPU的几倍甚至一个数量级以上,但问题在于只擅长它设计时针对的那几类算子,模型一变架构就抓瞎。第三条就是可重构芯片,硬件上提供一组可配置的计算单元和互连网络,通过配置码流在运行时改变电路功能。算卷积时把PE阵列配成乘累加链,算Transformer时再重构成新的拓扑,一套硬件吃多种负载。
三条路线放在一起看,各自的取舍会更清楚:
| 路线 | 灵活性 | 能效 | 开发周期 | 典型场景 |
|---|---|---|---|---|
| GPU | 高 | 中 | 短 | 通用训练与推理 |
| 专用ASIC | 低 | 高 | 长 | 流量稳定的单一模型 |
| 可重构芯片 | 中 | 中高 | 中 | 算子稳定但模型迭代快的场景 |
所以可重构的本质是在通用性和专用性之间找一个工程上最划算的平衡点。它不适合跟GPU比通用,也不适合跟ASIC比单点性能,它赢在“场景多变但算子有限”的中间地带。AI推理正是这个地带的典型代表:算子种类少、执行模式相对固定,但模型结构变化快,专用芯片跟不上版本迭代,GPU能效又不划算,可重构芯片就找到了自己的位置。这也是为什么2020年前后,学术界和工业界几乎同时把目光汇聚到这个方向。
1.3 半导体工艺视角下的能耗物理本质
聊能效绕不开半导体物理。数字电路功耗的基本公式是P = αCV²f,其中α是翻转率,C是负载电容,V是工作电压,f是时钟频率。降低功耗最直接的手段是降电压,但电压低到一定程度会受阈值电压的限制,漏电功耗占比快速上升,这也是先进工艺在性能之外对能效帮助同样关键的原因。更深一层,可重构芯片的能效优势在物理层面是有依据的:它把计算资源组织成专门的数据通路,翻转率更低、负载电容更小,单位有效计算消耗的能量自然比通用处理器少。这些底层的物理约束决定了可重构芯片的天花板在哪里,也决定了设计者在功耗优化上能玩的空间有多大。看专刊论文时如果能带着这层物理直觉去理解各种能效数字,会对论文里的优化手段有更清楚的判断。
2. 可重构芯片的核心架构设计拆解
2.1 细粒度与粗粒度:两条技术路线的本质差异
可重构芯片按配置粒度分成两大类。细粒度路线的代表是FPGA,基本单元是查找表(LUT)和可编程开关,最小配置单位是bit级。它灵活性极高,几乎可以实现任意数字逻辑,但代价是配置码流极其庞大,重配置耗时往往在毫秒级以上,而且用LUT实现算术运算时资源利用率偏低,相同功能比ASIC多花好几倍面积。粗粒度可重构架构(CGRA)则完全不同,基本单元直接做成ALU、乘累加器(MAC)、处理单元(PE)这类粗粒度算子,最小配置单位是字级。配置信息大幅缩减,重配置时间可以压到微秒级甚至百纳秒级,面积效率也更高,但灵活性相对受限,只能高效实现预先定义好的那类运算。
这期专刊讨论的重点明显偏向CGRA。这个选择是合理的:AI计算的算子是相当规整的,卷积、矩阵乘、激活、池化,本质都是固定模式的算术和访存操作,不需要用LUT去抠每一位布尔逻辑。用CGRA映射这类规则计算,硬件开销小、能效高,灵活性损失也完全可接受。我觉得读这期专刊的时候,脑子里要始终带着这个粒度概念——它决定了后面所有架构参数设计的逻辑起点。
2.2 CGRA处理单元阵列的参数选择与互连设计
PE阵列是CGRA的心脏。典型的组织方式是二维阵列,每个PE内部包含ALU、寄存器堆和一小块本地存储,PE之间通过可配置互连网络连接。关键设计参数有四个:阵列维度、数据位宽、互连拓扑、流水深度。拿一个8x8阵列、16bit乘累加单元来算笔账:每个PE每周期完成一次MAC,峰值就是64次MAC/周期;假设时钟跑到500MHz,峰值算力就是32 GMAC/s。这个数字看着不小,但实际映射卷积时还要考虑权重怎么广播、特征图如何在PE间流动、中间结果存放在哪里。互连网络设计不好的话,PE利用率可能只有一半,纸面峰值根本发挥不出来。
专刊里有一篇论文专门对比了不同互连拓扑对卷积映射效率的影响,结论是混合拓扑——邻居直连加行广播——在面积开销和映射灵活性之间平衡最好。这个结论跟我在实际工程中的观察是一致的。邻居直连适合让数据沿计算链流动,行广播适合把权重高效分发到同一行所有PE,两者一配合,常见卷积核的映射就能获得很高的PE利用率。另一个容易被忽略的参数是PE的本地寄存器堆深度:太浅会导致数据不得不频繁去阵列外的共享存储取,增加互连压力和延迟;太深又浪费面积。我一般建议按“能放下一个输出通道所需的最长临时数据链”来估算深度,宁可多留两成,不要卡得太死。
2.3 静态配置与动态重构:分层配置的思路
可重构芯片的配置机制分为静态重构和动态重构。静态重构在任务开始前配置一次,运行期间保持不变,实现简单、可靠性好,适合负载固定的场景。动态重构则在任务运行中按需切换配置,收益是能时分复用硬件资源:一个PE阵列可以通过时间切片跑不同算子,硬件利用率大幅提升。代价是配置存储、配置分发逻辑和切换开销都上来了。
专刊里有论文提出了分层配置的方法:把配置分成全局配置和局部配置,全局配置负责阵列的整体拓扑和互连模式,局部配置只修改部分PE的算子类型或参数。这样切换一个算子时只需要更新少量局部配置,把配置时间从微秒级压到百纳秒级。这个思路很像操作系统的两级页表,本质是稀疏更新。我自己做动态重构时一个很重要的心得是:要在编译期分析计算图,把可以复用的算子簇归到同一个配置上下文,运行时尽量降低配置切换频率——切换不是免费的,每一次切换都有时间成本和潜在的流水线排空惩罚。
3. 面向AI计算的能效优化关键策略
3.1 数据复用:能效的第一杠杆
AI计算能效优化,数据复用永远是第一优先级。卷积计算有一个天然特性:同一个权重会被多个输入位置复用,同一个输入数据也会被多个卷积核复用。如果把复用做足,让数据留在片上反复使用,片外访存次数可以下降一个数量级以上。衡量这个能力的关键指标是计算访存比(arithmetic intensity),单位是FLOP/Byte或MAC/Byte。
举一个具体例子。假设一个卷积层输入是56x56x64,权重是3x3x64x64,输出也是56x56x64。每个输出像素要计算3x3x64 = 576次MAC。如果采用输出驻留(output stationary)数据流,每次产生一个输出需要读入的权重和输入数据都很多。但权重和输入在相邻输出之间是可以复用的。采用权重驻留(weight stationary)策略,把权重提前加载到PE本地存储,输入数据在多个PE间广播复用,计算访存比就能从个位数提升到几十甚至上百,能效差距随之拉开一个数量级。专刊里讨论数据流设计(dataflow)的论文,核心就是在各种驻留策略之间做权衡。不同的卷积形状、不同的阵列规模,最优数据流并不一样,需要实际遍历比较后选型,不能一招吃遍天。
3.2 算子映射与编译器:决定阵列利用率的关键一环
有了硬件,真正决定性能上限的是编译器。CGRA的编译问题本质上是调度加放置的组合优化问题:把计算图的每个算子分配到合适的PE,确定它们在时间轴上的执行顺序,同时最小化数据冲突和通信开销。这个问题被证明是NP完全的,所以实际编译器都采用启发式算法,比如列表调度加模拟退火、基于图着色的放置策略,或者聚类加贪心的混合方法。
专刊里有篇文章比较了不同映射策略对能效的影响,结论非常直观:数据在物理位置上的布局往往比PE算子的选择更重要。如果两个相邻计算节点被映射到物理距离很远的PE上,数据要穿过多跳互连,不仅延迟增大,互连网络的动态功耗也明显上涨。把计算链紧密放置在相邻PE上,数据沿邻居通道直接流动,整体功耗可以省20%到30%。这也是为什么映射算法的目标函数不能只看PE利用率,必须把通信开销量化进去。我建议做CGRA编译器的人一定要设置一个通信感知的目标函数,哪怕只是用简单的曼哈顿距离加权,映射质量都会有立竿见影的提升。
3.3 混合精度与稀疏化:把模型冗余变成能效红利
AI模型的容错特性给能效优化打开了另一扇门。多数推理任务用INT8精度绰绰有余,部分对量化不敏感的层甚至可以用INT4,而训练过程则需要FP16甚至FP32。如果硬件支持混合精度,并能按层动态切换精度模式,精度和能效之间就能找到最佳平衡。可重构芯片在这件事上有天然优势:PE内部的ALU可以设计成位宽可配置的模式,比如一个16x16乘法器在特定配置下可以切分成两个并行8x8乘法器。
专刊里有论文评估了不同精度下的能效变化:从FP32切到INT8,计算能效大约提升4倍,存储和访存带宽需求也同比例下降。但混合精度不能盲目使用。我的实操经验是:先用校准集跑一遍逐层的数值分布统计,找出对量化敏感的那几层,保留高精度,其他层降位宽。模型精度损失通常能控制在0.5%以内,整体能效提升却非常可观。稀疏化的逻辑更直接:剪枝后模型里大量权重为0,硬件如果能跳过零值计算,有效算力利用率和能效都会上升。但稀疏计算的代价是索引开销变大,数据流变得不规则。专刊里“稀疏感知”PE阵列的做法是通过配置位控制无效数据跳过,在50%稀疏度下实测获得接近1.8倍的加速,这个方向在落地项目里很有价值。
4. 专刊全景:论文覆盖的主要方向与代表性技术
4.1 从架构到工具链的完整研究链条
拿到专刊目录时,第一感觉是覆盖面很全,基本把可重构芯片从底到顶的各个环节都串起来了。底层有CGRA阵列架构设计、可重构微处理器、类脉动阵列混合架构;中层有配置生成、映射编译和自动调度框架;上层有面向目标检测、语音识别等具体应用的系统级方案;横向还有基于仿真和流片实测的功耗评估方法。这个结构对读者非常友好:你可以顺着架构、编译、应用这根链条建立完整体系,而不是只在某个点上看一堆孤立论文。我特别建议刚入门的人按这个链条顺序读,先了解硬件能提供什么,再看编译怎么发挥硬件,最后看系统层面的瓶颈在哪里,这样认知是立体的。
4.2 三个值得反复读的代表方向
第一个是动态可重构验证平台。真正做过可重构芯片的人都知道,动态重构最大的工程难点是验证:同一块电路在不同配置码流下功能完全不同,传统仿真器很难自动覆盖所有配置空间。专刊里那篇验证平台的文章,把配置空间遍历、运行时功能检查和故障注入做成了闭环。这个方法我后来在自己的项目里借鉴过,非常好用,尤其是配置空间遍历那一套,比手写定向激励靠谱得多。
第二个是稀疏化与可重构的结合。稀疏模型加可重构阵列,听上去很美好,但真正落地有大量细节:零值跳过的判断逻辑放在PE内部还是互连层?索引信息存储在哪一级存储层次?如果判断逻辑本身消耗的功耗大于跳过零值省下的功耗,那就得不偿失。专刊里这个方向的工作把这些细节做得比较扎实,值得精读。
第三个是片上网络(NoC)与可重构阵列的融合。当PE阵列规模变大,总线互连不可持续,NoC成为必然选择。但NoC的路由延迟和动态功耗不可忽视。专刊里有论文根据负载特征设计可重构路由策略,运行时按当前算子动态调整路由算法,比固定路由节省约15%功耗。这个思路说明,可重构的理念不仅能用在计算单元上,也能用在互连结构上——整个芯片从上到下都是可以动态适配的资源。
4.3 从论文数字到真实芯片:工程落地的现实差距
论文里跑出来的数字都很漂亮,但从RTL到真正的芯片之间,还有大量论文不会写的现实问题。时钟树如何收敛、IR drop怎么控制、配置寄存器的可测试性设计(DFT)怎么做,每一项都是流片前必须过的坎。这里特别想提一个容易被低估的问题:可重构芯片的可测性。同一个PE在不同配置下功能不同,生产测试时需要对典型配置分别验证,测试时间会随着配置数量线性增长,测试成本不可小觑。专刊里讨论测试的篇幅不多,但这是量产时绕不开的硬约束。我给创业团队的朋友的建议是:架构定义阶段就要把BIST(内建自测试)方案规划好,把测试配置压缩到少数几种覆盖性最高的典型模式,否则流片回来之后的测试环节会变成真正的噩梦。
另一个现实差距是功耗评估的方法论。RTL仿真跑功耗太慢,门级仿真精度高但工程量大、耗时长。我的经验是把门级功耗分析用在几个关键节点上做标定,然后建立一套基于翻转率和负载电容的经验插值模型,估算整个芯片全场景的功耗分布。精度比不上门级全面分析,但迭代速度快一个数量级,对于架构早期选型完全够用。
5. 入门路径与实操避坑指南
5.1 新手如何系统学习可重构芯片
如果你看完专刊想入坑这个方向,我建议按下面的路径走。第一步补体系结构基础,把流水线、存储层次、并行计算这几块吃透,这些是理解任何加速器架构的地基。第二步上手FPGA,不用做多复杂的工程,在开发板上写一个简单的卷积加速器,亲身体会可配置逻辑到底是怎么回事,配置码流如何改变硬件行为。第三步读几篇经典论文,把可重构计算的历史脉络理清楚。第四步才是精读这期专刊,当你有了一定的硬件直觉,再回来看这些论文,会发现很多当时觉得抽象的参数选择一下子就通了。
这里还想多说一句:不要一上来就扎进编译器的细节。编译器是CGRA最难的部分,但它的目标函数、调度策略都建筑在对硬件的理解之上。你先搞清楚PE阵列怎么组织、数据怎么流动、配置怎么切换,再回头看调度算法,会顺畅很多。顺序反了,很容易被一堆调度术语劝退。
5.2 工具链与原型验证的务实选择
工具链是可重构芯片落地最痛的一环。商业FPGA工具链成熟,但面向LUT级逻辑,与CGRA的抽象层次不同。科研和早期项目通常用自定义编译器,但完全从零写一个CGRA编译器工作量巨大。我的建议是:做原型验证时,先基于高层次综合(HLS)工具把算子级的C/C++代码综合成RTL,搭一个简单的PE阵列跑起来,验证架构可行性。然后再用手写的映射器替换HLS的调度器,逐步精细化。在芯片本身的验证上,建议采用仿真加FPGA原型双轨制:仿真跑全面功能覆盖,FPGA原型跑真实应用负载提取性能和功耗特征。这两个结果对齐了,流片才有底气。
5.3 我踩过的几个坑与排查心得
最后分享几个实操中踩过的坑,都是真金白银换回来的。
| 常见问题 | 典型表现 | 我的处理办法 |
|---|---|---|
| PE间通信瓶颈 | 阵列利用率掉到40%以下 | 增加行广播通道,权重按行并行分发 |
| 配置存储容量不足 | 频繁片外加载配置,性能骤降 | 容量扩到覆盖单层全部算子,加配置预取 |
| 配置切换数据不同步 | 切换后出现随机错误结果 | 配置接口加入barrier同步,切换前排空流水 |
第一个坑是低估PE间通信瓶颈。我第一次设计阵列时只算了PE的乘法吞吐峰值,结果跑大尺寸卷积时,互连带宽成了瓶颈,阵列利用率掉到40%以下。排查了很久才定位到是行广播通道缺失。后来增加了行广播通道,把权重分发从逐PE串行改成按行并行,利用率才回到70%以上。设计初期就要把通信带宽当作和计算峰值同等重要的指标。
第二个坑是配置存储容量给少了。做动态重构时,需要把多套配置码流放在片上。我最初只给配置存储分配了一小块区域,结果跑一个深度网络时,没几个算子就要去片外加载配置,性能损失惨重。后来把配置存储容量扩到能覆盖单层全部算子,并做了配置预取,问题才解决。配置存储的容量底线是要能装下计算图一个阶段的所有算子配置,这个规则我到现在都还在用。
第三个坑是忽略了配置切换时的数据同步。动态重构时,如果新配置的算子需要读取上一种配置产生的数据,而数据还在流水线上没有写回,切换就会出错。这是一个很隐蔽的时序问题,仿真里不一定能触发。我的解决办法是在配置接口里加入一个显式的barrier同步信号,切换时先等流水排空,再更新配置、再恢复执行。看起来牺牲了一点切换速度,但可靠性大幅提升。专刊里关于运行时管理的论文也提到了类似机制,可见这是行业里的通病。
我自己在实际做这个方向的体会是:可重构芯片不是新概念,AI计算给了它第二次生命。这期专刊的可贵之处在于,它把国内一系列真实的研究工作聚成了一个体系,既有架构创新的闪光点,也有工程落地的务实讨论。如果你在做AI芯片相关的事,或者正琢磨把某个负载从通用GPU迁到更省电的平台上,花时间把这期专刊读一遍,大概率能在架构选型和能效优化上得到不少启发。
最后分享一个小技巧:读这类专刊论文时,别只看结论里的漂亮数字,先看它的仿真条件、工艺节点、数据精度和模型结构。把条件对齐了,数字才有可比性。芯片这行,脱离具体假设条件谈性能都是空谈。