1. 为什么通用芯片跑不动大规模AI推理:AI负载的三个本质特征
先说一个我这些年常被问到的问题:"直接上GPU不就行了吗,为什么还要专门做AI芯片?"抛开功耗和成本的账,更根本的原因是:AI推理负载和传统计算负载的脾气完全不一样。你拿一把菜刀去雕花,不是雕不出来,而是废料太多、效率太低、刀也钝得飞快。
第一个本质特征是访存密集,而且访存模式极其规律。跑一遍常见的主干网络就能看到,不管是卷积、全连接还是注意力机制里的矩阵乘,算子的核心计算量集中在矩阵乘法上,但每个算子前后都跟着大量中间张量的写入和读出。传统CPU靠大Cache和大乱序窗口掩盖访存延迟,GPU靠大规模线程并行和极高的访存带宽硬顶,但两者的设计思路都是"数据在寄存器里待不住、计算部件等数据"这个前提下做补救。而AI芯片真正该做的,是把数据搬移这件事本身当成头号优化目标——后面我会详细展开,这是术语里常说的"数据流(Dataflow)"设计的动机。
第二个本质特征是计算模式高度同构。AI网络里95%以上的计算量是矩阵乘加(MAC),剩下的是激活函数、归一化、Softmax这类元素级算子。MAC操作语义简单、无分支、无依赖乱序,完全不需要通用处理器那套分支预测、乱序执行、缓存一致性协议。把这些复杂机制全拆掉,省下来的面积和功耗就是纯算力。这也是为什么专用芯片能用一半甚至更低的频率和功耗跑出几倍于通用芯片的吞吐。
第三个本质特征是精度窗口可以被压缩。推理模型经过量化后,INT8在很多场景下精度损失可以控制在误差范围之内,某些场景甚至走到INT4。通用处理器为了兼容各种数值类型,不得不保留FP32/FP64的高精度执行单元和对应的寄存器堆,这些晶体管在执行INT8推理时大部分是空转的。AI芯片可以完全为低精度专用化,用同样的硅片面积塞进更多运算单元。
这个开头并不是理论铺垫,而是整个软硬件设计最初的决策锚点。后面每一步选型——要不要做脉动阵列、指令集怎么定、编译器后端怎么拆算子——都是围绕这三条特征展开的。搞清楚这三个本质,再看市面各种AI芯片的架构就不迷糊了:凡是做得好的,基本都在访存优化和MAC阵列利用效率上下了功夫;凡是"流片很顺但跑不动模型"的,几乎都是在数据带宽或是计算阵列利用率上出了窟窿。
2. 架构分水岭:从指令流到数据流的计算范式转变
2.1 脉动阵列:数据自己走到乘法器门口
传统处理器走的是"指令流"路线:一条条指令从指令Cache取出来,译码后告诉ALU去寄存器里拿数据、做什么运算。数据是"被拉"到计算单元面前的。AI芯片普遍换成了"数据流"路线:把数据按照固定节奏"推"进二维的乘累加单元阵列,每个单元只需要处理从相邻单元过来的数据,算完再传给下一个单元。这就像流水线厨房,食材按传送带依次经过每个工位,每个工位只处理到自己面前的食材,不用满厨房跑。
脉动阵列(Systolic Array)是这类架构里最经典的形式。一个N x N的PE阵列,左边进激活矩阵,上边进权重矩阵,每个PE内部做一个乘加运算,部分和沿对角线方向累加传递,最终在阵列右侧得到输出。这样做最大的收益是数据复用——同一份权重从上面流进去之后,会被同一行所有PE依次使用;同一份激活从左边进入后,会被同一列的所有PE依次使用。外部访存次数从O(N^3)次直接降到O(N^2)次,这个差距在矩阵规模变大时是数量级的。
我实际参与设计过的某个模拟项目,最开始用256个PE组成16x16阵列,频率500MHz,理论算力是4T MAC/s(约8 TOPS INT8)。第一版仿真跑下来,ResNet-50的单帧延迟远达不到预期。排查下来问题很典型:输入输出的数据格式转换模块成了瓶颈——外部DDR读上来的数据是行主序排列,但进入脉动阵列前必须按列流水重新组织,这个重排逻辑流水线设计不当,直接把有效吞吐砍掉了四成。
这是个非常容易踩的坑:PE阵列本身的计算效率,完全取决于数据进出阵列的匹配度。阵列内部算得再快,输入侧停摆一秒,输出侧也拿不到结果。做架构的人容易困在"怎么让PE利用率更高",但真正决定上限的往往是数据供给链路。
2.2 可重构数据流:编译器直接编排计算次序
脉动阵列适合矩阵乘法这种固定形状的算子,但AI网络里还有大量不规则算子,比如各种尺寸的卷积、动态形状的注意力矩阵、稀疏化之后的不规则访问。为了兼顾规则算子的高效和不规则算子的灵活性,另一个被反复验证的设计方向是可重构数据流架构(Coarse-Grained Reconfigurable Array,CGRA)。
通俗讲,CGRA就是一块布满PE的网格,PE之间的互联关系不是焊死的,而是由一组配置字(Configuration)在运行时决定。编译器在编译阶段就把一个完整的算子图映射到这块网格上,哪些PE负责哪一段运算、数据走哪条路径、在哪里暂存,全部提前排好,运行时只需一次性下发配置即可。这有点像把"菜谱"直接编排成"后厨动线图":谁切菜、谁配菜、谁掌勺都定死,开工后不再需要总厨逐条指挥。
这种架构的挑战在于编译器。把算子逐一分配到PE上,本质是一个约束满射问题:算力时序要匹配、片上SRAM容量要装得下中间结果、PE间的通信延迟要可控。我见过不止一个团队把硬件流片规划得很早,软件映射工具却是临时拼凑,最后模型能跑的算子覆盖率不到预期,大量算子退回通用计算单元执行,性能断崖式下降。所以如果你在看这类AI芯片方案,有一个判断维度很直接:它的编译器工具链能覆盖多少个公共算子、映射失败率是多少,比单纯看峰值算力重要得多。
2.3 数据流架构怎么选:三种主流方案对比
在真正动手选型时,团队通常会在几种数据流方案之间做取舍。我整理一个对照表,这是我在多个项目里实际比较后得出的判断框架:
| 方案 | 核心思路 | 优势 | 短板 | 适合场景 |
|---|---|---|---|---|
| 脉动阵列 | 数据沿固定方向流水穿过PE阵列 | 结构规整、面积效率高、功耗好 | 对算子形状敏感、不规则算子利用率低 | 大矩阵乘为主的规则模型 |
| 近存/存内计算 | 把计算单元搬进存储单元附近或内部 | 极大压减数据搬移开销 | 模拟量计算精度难控、数字方案面积开销大 | 带宽受限的规模推理 |
| 可重构数据流 | PE网格互联可配置,编译器编排 | 灵活覆盖多种算子、空间并行度高 | 工具链复杂、编译映射困难 | 算子形态多变的边缘模型 |
还需要补充一点容易被忽略的建议:对许多标量逻辑(如控制流、指针跳转、动态shape处理),不要强行往数据流架构上靠。任何好用的AI芯片都会在数据流阵列之外保留一个小的通用处理器核或向量单元,专跑这类"计算密度低但逻辑复杂"的代码。纯粹追求"全数据流化"的芯片,软件兼容性差,编译器负担重,实际落地效果往往不如混合方案。
3. AI芯片硬件侧的完整设计链路:从需求拆解到物理实现
3.1 需求拆解:用真实推理模型做预算定额
硬件设计的第一步不是画框图,而是建立一份可量化的性能预算表。这里说一个我在多个项目里一直坚持的做法:不要拿理想化的算子浮点数量做规划,要拿真实模型在目标延迟约束下的算子分解结果来倒推。
举个例子,假设目标是在8ms内跑完一个常见的视觉模型单帧推理。用性能分析工具对模型做逐算子剖析,得到每个算子的MAC数量和访存量,然后至少三个口径同时对齐:一是计算侧预算,所有MAC除以PE阵列算力,得出纯计算耗时;二是访存侧预算,所有中间张量与权重加起来的字节数除以有效带宽,得出数据搬运耗时;三是排队与调度开销,包括算子之间同步、控制流处理、DMA启动延迟等。
三份预算都做完之后,你会立刻看到瓶颈位置的真相。很多情况下,计算侧预算只占延迟期望的三分之一,访存侧预算却直接爆掉。这说明问题不在PE阵列大小,而在内存带宽——你花大价钱多放一倍PE是无效投资,因为数据根本喂不进去。设计阶段尽早做这个练习,能省下大量后期返工。
3.2 芯片内部结构划分与数据通路设计
明确了预算之后,才会进入芯片内部的结构设计。一个典型的AI芯片SoC可以拆成六个部分:AI计算核心阵列(数据流引擎)、片上存储层次(SRAM/Cache)、数据搬运引擎(DMA)、通用控制处理器、外部存储接口(DDR/LPDDR/HBM控制器)、以及各种配套的IO接口。
这六部分里,最容易设计失衡的是片上存储层次的容量分配。层一SRAM离PE最近,延迟最小但容量小;层二SRAM或Cache容量大但延迟高;再往下是DDR。AI芯片设计师最需要拿捏的功夫,是让每层存储的容量和带宽与它服务的计算需求匹配。一个经验值是:对典型的INT8推理模型,若PE阵列单拍能消费C个字节输入(等于阵列宽度×字节数),那么片内至少要有足够的缓冲让数据供给在大部分时钟周期内不中断。这个"大部分"做到90%以上,调度端才算及格。
数据通路设计里的另一个诀窍是多级流水与乒乓缓冲。DMA从DDR取回的数据,先写入片外的双缓冲,等当前帧计算的同时预取下一帧数据,让访存和计算并行。这里要特别注意DMA描述符的编排:描述符链要提前建好,中断响应不能走慢速的中断服务例程,最好由硬件调度器直接消费描述符队列,避免CPU介入。
3.3 RTL设计、覆盖率导向验证与FPGA原型
硬件逻辑实现阶段,整套验证流程和数字IC设计是相通的,但AI芯片有几个特殊性必须重点覆盖。
第一是数据格式相关验证。AI芯片通常要同时支持FP32、BF16、INT8、INT4等多种格式,还可能混精度执行。验证环境必须覆盖格式之间的转换精度、饱和边界、舍入模式,这些边界条件如果不专门构造用例,极易漏测。我见过不止一次的"流片回来精度异常"问题,根因就是验证向量未覆盖INT8乘法结果的饱和截断路径。
第二是RAM/寄存器访问冲突。AI芯片内部配置空间巨大,软件栈运行时会频繁写寄存器。多核同时访问同一寄存器组导致的士冲突,在仿真阶段很难全部暴露。稳妥做法是形式化验证(Formal Verification)覆盖所有寄存器读写地址窗口,并对每个寄存器明确归属权。
第三是低功耗验证。推理芯片运行能耗是重要卖点,所有时钟门控信号、存储体唤醒逻辑都需要专门的功耗感知仿真去验证,不能只靠综合工具自动插入门控。这里最容易出问题的是突然唤醒大容量SRAM时产生的电源毛刺,轻则逻辑误触发,重则芯片直接复位。
至于FPGA原型验证,当前主流做法是拿多颗大容量FPGA拼接,把AI计算阵列和存储子系统映射上去,跑真实的模型推理。原型验证能提前暴露软件栈与硬件交互的大多数问题,比如DMA描述符配置错误、中断优先级不合理、寄存器初始化遗漏等。但原型验证的时钟频率远低于真实芯片,性能数据只能作为趋势参考,不能作为最终规格。
3.4 物理实现阶段AI芯片的两大压力源
物理后端(Place & Route)阶段,AI芯片比其他数字芯片更痛苦的是两个地方。第一是巨大的片上存储面积占比。现有AI推理芯片的SRAM通常占据芯片面积的三到五成,这意味着金属层走线资源极度紧张,电源网络的IR Drop也容易超标。后端团队需要提前做电源网格规划,把SRAM体间的电源环预留好,否则后期切到高负载用例时动态压降会触发时序失效。
第二是高速外部存储接口与内核逻辑的时钟域同步。DDR或LPDDR接口频率高,和内核数据流阵列通常不同频,跨时钟域处理不当就会产生偶发性的数据错误。这种问题在仿真阶段几乎不会被发现,只有跑到长时间压力测试时才会出现。我的建议是:从设计第一天就把跨时钟域的同步级数和握手机制定清楚,不要拖到后端阶段才去补救。
4. 软件栈才是隐形战场:编译器、运行时与算子调度
4.1 为什么说"芯片一半的价值在软件"?
不少第一次接触AI芯片的团队有个朴素想法:硬件流片成功就好,软件随便配一套能跑通Demo就能交差。这种想法几乎必然导致项目烂尾。因为现代AI模型的更新速度远超硬件迭代周期,你在硬件设计阶段确定的算子集合,到软件发布时很可能已经过时。如果没有一个足够灵活的软件栈来适配新算子,芯片就只能跑固定网络,市场价值会大打折扣。
我自己的经验判断是:AI芯片的软件栈至少要覆盖四层——模型前端(导入和优化计算图)、算子映射器(把算子划分到计算阵列和通用核上)、运行时调度器(管理DMA、同步、资源分配以及多任务并发)、驱动接口(向上层框架暴露统一API)。这四层缺一层都不行。
4.2 算子映射的本质问题:怎么把大算子拆到小计算单元上
算子映射是整个软件栈里最硬核的部分。以一个大Size的卷积举例,硬件PE阵列只有16x16,矩阵尺寸是256x256,直接放不进去,必须先切块(Tiling)。切块策略决定输出张量怎么写回内存、累加器怎么处理部分和、边界数据是否需要重复读取。
这里有个容易忽略的细节:切块大小不是越大越好。切块越大,PE利用率越高,但片内存储需要的中间缓冲区越大,可能需要频繁换入换出;切块太小,则数据重读率上升,访存总量变大。具体切块尺寸需要在编译期结合PE阵列尺寸、片内SRAM容量和内存带宽做联合搜索。我们团队当时的做法是:先按SRAM容量上限枚举可行的分块组合,再用一个成本模型评估每个组合的预估执行周期和访存流量,最后选Pareto最优解。这个成本模型要在仿真器上标定,保证它反映真实硬件行为。
除了切块,还有算子融合。相邻的卷积后面紧跟BatchNorm和ReLU时,完全可以在PE阵列里等一个Tile算完就立即做缩放加ReLU,不用把中间张量写回DDR再读出来。算子融合的收益在内存带宽紧张时极其显著,先是省掉了两次全量访存,其次减少了DMA描述符数量,降低了调度开销。很多编译器在做融合时只盯着计算图层面的模式匹配,却忽略了融合后对片内缓冲的生命周期影响,反而把SRAM占满导致无法双缓冲,引发性能回退。所以融合决策必须和内存分配一起做,不能拆开。
4.3 运行时调度的核心:让硬件永远别闲着
运行时调度器的工作内容,一言以蔽之:在正确的时间点,把正确的数据放到正确的位置,并把计算命令下发给对应引擎。真正做起来难在并发和同步。
以单算子排队执行的方式举例,逐个算子上报完成中断再启动下一个,肯定功能正确但性能很差。优化的调度是把多个算子以流水线方式重叠:DMA正在搬运算子B的输入时,PE还在计算算子A;或者让两个PE子阵列分别跑两个小算子,粒度更小地利用空闲资源。要做到这个粒度,运行时必须精确知道每个算子的依赖关系与资源需求,并且要有足够细的硬件同步原语。
硬件同步原语是整个运行时设计的基石。最常用的是事件/邮箱机制:某个硬件引擎完成一个任务后发送事件,另一个引擎等待该事件后再启动。做同步原语时要注意加锁的粒度——粒度过粗会让两个引擎互相阻塞,粒度过细则同步开销接近甚至超过任务本身。好的设计是让同步发生在引擎与引擎之间,而不是每次都穿越全局调度器。
4.4 编译器和驱动怎么协作不出问题
最后一块是编译器和驱动之间的接口设计。很多AI芯片项目出问题,都出在"编译器生成的任务图"和"驱动实际执行的命令"对不上。编译器假设寄存器配置了A,驱动可能因为初始化时序晚了一拍,把配置覆盖了。
我建议的做法是引入一个稳定的中间表示(IR)加上任务描述结构。编译器的最终产物不是直接下发的寄存器值,而是一份结构化的任务描述,包含算子类型、各缓冲区地址、DMA描述符链、同步事件ID等信息。驱动只负责把这任务描述按硬件约定翻译成寄存器序列。这样编译器、驱动、硬件的职责边界清晰,任意一侧的调整都不至于牵一发而动全身。但注意,这套IR和任务描述结构必须尽早冻结——项目初期改动频繁没关系,但在RTL完整验证之前一定要稳定下来,否则后面每一天都是适配地狱。
5. 软硬件协同设计:边界划分与迭代节奏
5.1 什么该固化到硬件,什么该留给软件
协同设计的核心问题其实是:哪些功能固化到硬件里,哪些保留给软件去实现?这个问题的答案决定了芯片的灵活性和开发效率。
我倾向于遵循两条原则。第一,凡是主流模型里出现频率极高的原语,才值得硬化。矩阵乘、卷积、各种归一化、常见的激活函数,这些属于值得流片进去的高频操作。而一些还在快速演进的算子(比如各种新型注意力变体、多模态融合算子),更适合用通用计算单元加编译器混合实现,硬件层面只提供基础向量指令。第二,凡是与数据布局强相关的决策,尽量留给软件。数据在SRAM里的排列方式、算子切块的选择、双缓冲的缓冲区划分,这类决策高度依赖具体模型,硬件无法预知最优方案。让编译器去算,软件在运行时通过配置下发,是最合适的。
把这两条原则落地后,硬件与软件接口层的形态也就清晰了。不需要设计一个庞大的指令集,而是定义一组引擎配置寄存器加任务表。任务表的结构体里包含算子类型ID、输入输出地址、循环边界、数据步长、是否启用偏置或融合操作等字段,驱动只需定期向硬件队列表格写入新的任务描述即可。
5.2 仿真器驱动的前移式协同验证
软硬件协同设计另一个关键实践是从第一天就建立cycle级或近似cycle级的软件仿真模型。在没有真实芯片之前,软件栈所有的算子映射、切块搜索、调度策略逻辑,都在这套仿真器上验证和调优。仿真器必须能统计每条指令的执行周期、每个存储体的访问次数、PE阵列的时钟级利用情况,并输出带宽占用曲线。
为什么强调cycle级?因为AI芯片性能优化的核心手段——双缓冲、算子融合、多核并行——都是对时序敏感的。如果用功能级模型验证出的结论搬到硬件上,往往因为实际延迟和理想模型不一致而失效。这个仿真器需要和RTL做反复交叉验证:初期以RTL仿真为基准,把各模块的延迟数据标定进模型;模型标定完成后,大量架构探索都跑模型,只在关键决策点回到RTL确认。
我常用的一个迭代节奏是"两周一个循环":第一周,软件团队基于仿真器提出一项算子映射或调度优化;第二周,硬件团队评估该优化是否需要在硬件行为上增加新特性或修改约束,必要时改动RTL或寄存器定义;下一轮循环再验证改动后的收益。每轮改动都有量化的性能数据说话,避免"我觉得这个功能该加"这种拍脑袋决策。
5.3 异构多核的协同落脚点
现在稍微上规模的AI芯片很少是单一大核,更多是异构多核:若干个中型数据流引擎加若干通用CPU核,甚至可能挂一些专用加速器模块。异构多核的协同设计,除了前面说的任务划分,还得考虑负载均衡与通信开销之比。
一个运算密集的大矩阵乘法,拆给两个PE引擎并行执行,理论上接近两倍加速;但如果拆分的通信同步开销占总执行时间的比例超过10%,这个拆分就得不偿失。合理的做法是:大算子保持单引擎执行,多个独立小算子并行放到不同引擎上。等到软件任务队列里同时有几十个中小算子时,调度策略的价值才体现出来。设计初期就要准备好一个多任务队列,支持抢占、优先级排序和任务间的数据依赖链,让芯片在工作负载上来时不会显得"手忙脚乱"。
6. 做AI芯片这些年最容易翻车的几个地方
6.1 峰值算力崇拜与真实吞吐的差距
这是行业里最常见的陷阱:新闻稿里的TOPS数字非常好看,实际跑起模型来性能惨不忍睹。原因往往在数据供给和PE利用率的双重不足上。用前面提到过的成本模型认真算一算,你就会发现,同一个硬件在不同编译器优化水平下,真实吞吐可以差3到5倍。选型时遵循"以整模型推理延迟为准,不信单算子峰值"的原则,并且在评估多款方案时用完全相同的算子和完全相同的量化配置。
6.2 低精度量化的精度损失陷阱
INT8量化不是简单地把浮点张量四舍五入成整数就完事。分布裁剪、逐通道/逐张量的缩放因子、反量化的时机,都会显著影响最终精度。如果量化误差控制不当,模型精度掉点甚至出现"灾难性偏差",性能再高也没有意义。
几个实操建议:一是量化校准数据集的选取一定要覆盖真实部署场景的数据分布,不能拿训练数据直接校准;二是对敏感层(注意力层、归一化层)设置混合精度保护,只量化计算密集的层;三是误差敏感度分析一定要在硬件上做端到端回归测试时验证,仿真阶段的近似结论只能作为参考。力求在模型侧和硬件侧各做一层保护,才能控制整体掉点幅度。
6.3 验证覆盖不全:流片后的"幽灵Bug"
必须承认,没有任何团队能在流片前把硬件验证做到100%完备。AI芯片尤其难,因为它的操作模式高度依赖软件实时配置,寄存器组合空间巨大。我们踩过几次流片后才发现的问题,总结起来集中在三类:一是DMA边界条件下的地址越界行为;二是低电压条件下的SRAM保持稳定性;三是多种引擎同时启动时的仲裁优先级反转。这三类问题有一个共同点,都是只在长时间、高负载、多并发场景下才会被触发。
应对手段是提高软硬件联合压力测试的比重:在FPGA原型或是芯片回来后,用随机的算子序列不间断跑数小时甚至数天,同时实时监控错误计数、温度变化、时序裕量。这个方法虽然土,但历史上比很多形式化工具抓到的Bug都多。
6.4 工具链投入永远别省
我见过不少项目,硬件开发预算充足,软件团队却只有一两个人,还被迫用早期不成熟工具链支撑所有模型验证。到了投片前才发现算子覆盖率不达标,性能关键路径没有优化完,后面整机厂商催Demo时完全被动。软硬件协同开发的成功经验是软件团队和硬件团队同时启动、同等资源、同一决策页面。编译器、运行时、仿真器的开发不可能在三个月内追平一年的差距,预留足够的时间,是协同设计中最重要的非技术要素。
7. 给后来者的一份实操清单
如果读完前面内容,你正准备启动一个AI芯片软硬件协同项目,我的建议是浓缩成下面五件事,每一条背后都是真实项目的代价换来的。
第一,建一个内容完整的模型库。不要只搭一两个知名模型,要把目标场景里可能出现的各种尺寸、各种算子形态都收进来。模型的算子分布直方图、访存分布、峰值内存占用,都要在项目启动前量化成文档。这决定你的架构评估是否靠谱。
第二,第一版仿真器必须支持"软件跑完整模型"能力。不要用零散的脚本验证硬件模块行为,从一开始就让编译器把模型编译成任务图,让运行时调度器在这个仿真器上完整执行。性能基线从模型端到端延迟开始记录,每个优化措施都对着同一个基线做增量改进。
第三,尽可能早地让最终用户试用工具链。在芯片还在RTL仿真阶段时,就可以让下游模型的部署工程师试着用你的工具链去适配真实模型,收集他们的反馈。这个反馈比任何内部评审都有价值。让工具链"难用但能用"的阶段越早暴露,留给打磨的时间越多。
第四,硬件寄存器定义的变更要有审批流程。寄存器一旦被驱动使用,以后任何宽度、地址、语义的变动都需要同时改硬件、驱动、编译器三处。建议从一开始就把寄存器定义做成结构化文档,软件层通过代码生成器自动维护头文件,避免手工改动的低级错误。
第五,投片前至少完成一轮完整的端到端压力测试。包括连续多天不间断跑多个模型、所有量化格式轮换、所有电源模式轮换。哪怕有些测试场景是重复劳动,也值得做一遍。芯片回来后发现的问题,修复成本是投片前的十倍百倍。
做AI芯片从来不是一场短跑,它更像一场马拉松加障碍赛的混合项目。真正的门槛不只在于流片和验证的能力,更在于软硬件之间那些看不见的接口约束、时序约定、任务调度共识。每一个细节都要有人认真较真,每一个环节都要有工具链和数据支撑。如果你打算进入这个领域,我给的最真诚的建议是:多花时间在"软硬件之间那条线上",它才是整个系统真正的主干。
在实际操作的这几年里,我的体会是:很多看起来高难度的架构问题,最终都不是被某个天才设计解决的,而是被一套严谨的协同流程和大量跨团队沟通慢慢磨掉的。硬件跟软件之间的日常对齐,比任何一次孤注一掷的架构创新都重要。希望这篇内容能帮你在自己的项目中少走几条弯路。