ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

SoC存储体系全景:寄存器、Cache、DRAM与Flash如何决定芯片性能

SoC存储体系全景:寄存器、Cache、DRAM与Flash如何决定芯片性能 我很少看到有人能把SoC里的存储讲清楚。大多数人看手机SoC天梯图盯着的是几个大核几个小核、主频多高、GPU几核但真正让两颗纸面参数接近的SoC在实际体验里拉开差距的往往是藏在CPU核心周围的那些存储单元。一个做嵌入式或者芯片验证的老手应该都有这种体会所谓性能很多时候不是算得快而是数据喂得快、喂得稳。这篇文章想做的就是把SoC里各类存储类型、它们的用途和核心差异完整梳理一遍——从教科书里的原理讲到你真去写驱动、调DMA、查缓存一致性时遇到的现实问题。1. 为什么SoC里是一整套存储物流系统而不是一个大仓库1.1 一个大而全的存储器方案为什么行不通先说一个我经常被问到的问题为什么SoC里不能就放一大块SRAM或者一大块DRAM把什么数据都装进去答案是没有任何一种存储技术能同时满足速度快、容量大、断电不丢、成本低、功耗低这五个诉求。寄存器堆速度快到能跟上CPU主频但一个bit就要二十多个晶体管512个寄存器的工程代价已经不小想拿它存几个GB的数据芯片面积和成本直接就爆炸了。SRAM同样快6个晶体管才能存一个bit密度低、漏电还不小适合做几MB到几十MB的片上缓存但撑不起主存。DRAM的电容密度高一个bit只要1个晶体管加1个电容所以能做到GB级别但电容会漏电必须周期性刷新而且延迟是几十纳秒起步。Flash/NAND能断电保存数据可是速度慢了一个数量级不说寿命还有限根本没法拿来当内存跑。所以你看到的每一颗SoC内部都是按温度层组织的离CPU越近的存储越快、越贵、越小离CPU越远的存储越慢、越便宜、越大。这不是设计者懒得统一而是物理规律和商业成本逼出来的分工。这个思路跟城市物流系统很像寄存器是快递员手里的登记本Cache是小区的临时货架DRAM是城市分拨中心Flash是远郊的保税仓。1.2 局部性原理存储层级存在的理论根基支撑这套层级能成立的理论依据是程序的局部性原理。简单说就是时间局部性刚访问过的数据很大概率很快再被访问一次。典型例子就是循环体里的计数器。空间局部性访问了一个地址它附近的地址大概率也会被访问。典型例子就是数组的顺序遍历。如果没有局部性每一条指令都去访问一个全新地址那么Cache基本是废的CPU只能天天等DRAM。但现实程序操作系统、编译生成的目标代码、视频编解码、数据库查询都高度符合局部性规律所以CPU往中间插一层又一层小容量高速缓存命中率就能做到90%以上、99%以上绝大多数访问根本不触达慢速存储。这也是整个SoC存储设计的根本逻辑不是去消灭慢存储而是用快存储把慢存储罩住让慢存储大多数时候闲着。1.3 从CPU核心到外部大容量存储的完整链条SoC里的存储体系如果按物理位置和角色分大致是下面这条链层级典型位置典型技术角色寄存器堆CPU核心内部触发器指令执行瞬时数据L1 CacheCPU核心内部SRAM指令与数据的一级缓存L2 CacheCPU簇内可共享SRAM一级缓存的缓冲L3 Cache / 共享缓存SoC全局SRAM/eDRAM多核共享的集散地TCM / 片内SRAMCPU核旁或SoC固定地址SRAM确定性延迟的实时数据主存控制器SoC内部LPDDR/DDR连接外部DRAM存储控制器SoC内部eMMC/UFS/SD连接外部FlashBoot ROM / eFuseSoC内部安全区ROM/eFuse启动和安全信任根在这条链里每一级都有它不可替代的岗位职责。接下来我会分别讲清楚它们各自是什么原理、为什么这个岗位非它不可、以及你实际写代码时最需要记住的那几个点。2. 易失性存储三兄弟寄存器、SRAM与DRAM这三位有个共同点断电即丢。区别在于速度、容量、价格和它们在SoC里干的事。2.1 寄存器堆一颗芯片里最贵的速记本寄存器堆是所有存储器中最快的因为它就是用触发器和组合逻辑做的放在CPU流水线的执行单元旁边。你在指令里写的R0、R1这些通用寄存器本质就是一组能在单周期内完成读出、写入、旁路转发的存储阵列。为什么它贵因为一个寄存器的bit在标准单元库里大约要20多个晶体管——除了存储用的触发器还要有多个读端口和写端口的地址译码逻辑。ARM的寄存器堆通常提供2个读端口1个写端口有的高性能核心会做到3读2写甚至更多端口越多布线越绕面积越大时序越紧。它只解决当下这一拍的问题。数据进了寄存器算完立刻就能用但寄存器容量太小一个核心通常也就百来个所以CPU在读写寄存器的同时必须在背后靠Cache和内存源源不断地供水。你可以这么理解寄存器是作战指挥桌上的地图真正的大部队都在后面的营地。2.2 SRAM6个晶体管守护一个bit的片区仓储SRAM的全称是静态随机存取存储器。静态的意思是只要供电它不需要任何刷新操作就能一直保持数据。典型单元是6T结构——两个反相器交叉耦合锁住状态再加两个传输门用于读写。SRAM在SoC里的存在感极强L1/L2/L3 Cache的数据数组和标签数组片内SRAM也叫System RAM / On-chip RAM比如一些MCU里的若干KB内存FIFO缓冲、显示控制器里的行缓冲、网络包缓冲SRAM最大的优点是访问延迟低且可控。一个接入CPU流水线的紧耦合SRAM理论访问延迟可以压到1到3个时钟周期。缺点也明显cell面积大同样的容量SRAM大约是DRAM的6到10倍面积静态漏电也高在低功耗SoC里是一个不可忽略的电源负担。做SoC选型时有个经验值同样工艺下1MB的SRAM和1MB的DRAM裸片面积差距大约是7到10倍。所以片上SRAM一般只做到几十KB到几MB真需要几十GB的临时存储必须走DRAM。这个成本和密度关系是SoC架构师不敢把所有临时存储都用SRAM的硬约束。2.3 DRAM和LPDDR主存扛把子与它的带宽账本DRAM的单元是1T1C——一个晶体管加一个电容。数据以电荷形式存在电容里电容会漏电所以必须周期性地读出来再写回去这就是刷新。DRAM为什么能做大容量因为单元结构简单、密度高。单个芯片就能做到8Gb、16Gb甚至更高几颗叠起来就凑成手机的8GB、12GB运行内存。真正值得抠细节的是带宽。 DDR/LPDDR的标称频率比如LPDDR4X 4266Mbps指的是每根数据线每秒传输4266兆比特。一条通道的位宽如果是16bit带宽就是4266Mbps × 16bit 68Gbps 8.5GB/s如果是双通道32bit那就翻倍到17GB/s。手机上现在很多用的是LPDDR5/LPDDR5X标称6400Mbps甚至更高位宽通常是64bit4个16bit通道算下来带宽到50GB/s以上。这和SoC性能的关系很大。你跑天梯图里的那些综合评测凡是大量搬数据的场景——文件解压、图像处理、游戏读场景——最后都会卡在内存带宽上。两个SoC的CPU算力接近时内存位宽高一级、频率高一级实际体验就能差出一截。所以很多旗舰SoC把内存控制器位宽拉到64bit甚至128bit不太常见于手机更多见于服务器本质就是在给数据通路扩水管。一个容易踩的坑标称频率和实际可达带宽差得远。因为DRAM的列访问有tRCD、tCL这些时序参数还有刷新和Bank切换惩罚实际读写效率通常只有理论带宽的70%到85%。评估SoC内存性能时最好用跑benchmark的有效带宽而不是拿频率乘位宽直接算。3. 非易失性存储梯队ROM、Flash与eFuse各管一段这一队存储即使断电也不丢数据是SoC的长期记忆。但它们各自的分工差别很大很多刚入门的人容易把Flash和ROM混为一谈。3.1 Boot ROM上电后的第一口饭SoC上电那一刻DRAM还没有完成初始化DDR的时序训练还没跑外部存储控制器还停在待配置状态CPU怎么取第一条指令答案藏在Boot ROM里。这是一块在芯片出厂时就被掩膜固化、不可修改的只读存储器固定在SoC地址空间的最高端或者最低端CPU复位后第一条取指就直接指向它。它干的活通常只有三件设置最基本的堆栈指针、时钟和看门狗。决定启动介质——从eMMC/UFS/NOR Flash/SD卡/USB哪一条路径启动。对后续加载器做认证。安全启动Secure Boot的信任根就锚定在这里如果Boot ROM里烧的公钥哈希没问题验签通过了才允许执行外部Bootloader。所以SoC的启动第一站必须是ROM而不是Flash或RAM。RAM上电全是乱码Flash的接口还没初始化只有固化在硅片上的ROM能保证CPU一上电就有确定的代码可跑。你看有关SoC芯片启动的资料时理解了Boot ROM这一环整个启动链路就先通了一半。3.2 NOR Flash与NAND Flash一字之差各自保的是不同命Flash家族里最常见的两个分支是NOR和NAND它们在SoC系统里的角色完全不同。NOR Flash支持随机读取字节级别寻址所以代码可以直接在Flash上执行这种能力叫XIPExecute in Place。CPU取指时直接访问NOR Flash的地址跑完就完事不用先拷进RAM。很多MCU和纯嵌入式系统的固件就是直接放在NOR Flash里执行的。但NOR容量做到几十MB就差不多了更大的容量成本不划算而且写入/擦除很慢也不适合频繁改写。NAND Flash则完全是为大容量设计的。它的读写以页和块为单位内部没有随机字节访问的概念天然不支持XIP。使用NAND时系统必须先把代码搬运到RAM里再执行。对应到手机SoC原本的Raw NAND大多被封装成了eMMC、UFS这类存储设备——内部是NAND颗粒加一个Flash控制器芯片对外提供块设备接口。SoC侧的存储控制器比如UFS Host Controller负责把SSD风格的命令翻译成对NAND的具体操作。选择逻辑很清晰启动和关键代码用NOR或Boot ROM因为它们要XIP或至少要做认证大容量用户数据和操作系统镜像用eMMC/UFS因为它们密度大、便宜掉电也不丢。速度上UFS 4.0的顺序读可以到几GB/s比NOR快一两个数量级但延迟依然远高于DRAM所以永远做不了主存。3.3 eFuse和OTP出厂即定连电都改不了的基因片段eFuse这个词听起来陌生但在每一颗SoC里几乎都有。它本质是一小块一次性可编程存储OTP出厂后用高电压把内部熔丝或者反熔丝烧断/接通完成一次写入之后永久锁定。eFuse里存的通常是芯片ID、版本、生产批次根密钥的哈希、公钥特殊功能开关安全存储区密钥加密用的密钥种子正因为烧录后不能再改它成了安全信任链的最上游。Secure Boot验签用的根公钥就存在eFuse里如果eFuse被物理攻击改了签名校验直接崩掉系统会拒绝启动。所以eFuse在设计上还会配访问保护和一次性锁定位防止驱动层软件随意读或者改。实际工作中接触eFuse的机会不多但一旦涉及量产烧录和加密方案就绕不开它。一个注意事项烧eFuse是不可逆操作量产前一定要反复确认要烧的内容真机打样阶段我见过因为测试脚本多烧了一个熔丝位导致整批样机安全功能降级的先例。4. Cache与TCM藏在CPU身旁的隐形仓储选错了真会误事这一章最容易被人忽略也最容易在实战中翻车。Cache和TCM紧耦合存储器看起来都是CPU旁边的高速SRAM但它们的架构角色完全不同。4.1 Cache为什么不是越大越好Cache的作用是缓存主存内容让CPU大部分时间都能命中快数据。L1 Cache通常分成指令缓存I-Cache和数据缓存D-Cache每个核心独享访问延迟大约2到5个时钟周期L2 Cache兼顾数据和指令在手机SoC里一般每核心或每簇一个延迟十几到二十几个周期L3 Cache通常是一个大簇CPU之间共享的延迟几十个周期容量可以做到8MB、16MB甚至更大。那为什么不把L3做到256MB原因有三面积和延迟的平方律。Cache越大物理走线越长地址译码越慢命中延迟反而升高。功耗。大容量SRAM漏电惊人手机SoC尤其受不了。一致性代价。多核共享缓存时一个核改了数据其他核的私有缓存要失效或更新容量越大、核越多一致性协议通信开销越重。天梯图里那些高分的SoC往往不是简单堆核心数而是在Cache层级和一致性协议上做对了设计。比如L2/L3的替换策略、预取器是否聪明、多簇间的一致性互连是否高效这些对综合性能的影响有时候比主频还显著。4.2 TCM没有命中风险、延迟确定的强制缓存TCM的定位不太一样。它不是缓存主存而是直接被CPU以固定地址访问的SRAM属于内存而不是缓存的影子。TCM的特点是只要你把它映射在固定地址那么每一次访问都必定命中延迟确定不会被替换策略踢走。这个特性对实时任务极其关键。拿中断服务程序举例中断来了代码和栈如果放在Cache里一旦被别的内容挤出去中断处理就会卡在缓存未命中上实时性就没法保证。而把关键ISR和栈放到TCM里每次中断进来都是固定周期内完成这才能满足硬实时的要求。ARM的Cortex-M系列就把TCM的思路普及给了整个嵌入式界代码和数据放进ITCM/DTCM后跑起实时算法很踏实。到了应用级SoC里同样存在类似角色比如专用SRAM块、Scratchpad RAM只不过名字不叫TCM。选型建议很直白确定性延迟需求强的数据放TCM/片内SRAM别把命放在Cache的命中率概率上。4.3 一次让我吃了大亏的缓存一致性问题这种感悟不是空谈。我有一次在带操作系统的SoC上调DMA接收网络报文流程是驱动程序配置DMA把数据写进一段内存缓冲区然后CPU去读它。按道理很简单但在某个优化级别下CPU读到的永远是旧数据。排查了很久最后发现DMA绕过CPU直接写的是DRAM而CPU这边对应的Cache行还保留着写DMA描述符之前的旧值。CPU读的时候命中了自己的Cache根本不知道DMA已经把新数据写到DRAM里了。解决办法是访问DMA缓冲之前做Cache Invalidate把相关行的缓存内容作废强制从DRAM读反过来CPU写完描述符要通知DMA读取数据得先做Cache Clean把脏数据刷回DRAM。这是一个所有做过DMA驱动的人都可能遇到的一致性问题。SoC里易失性存储的类型不只决定了延迟和容量还决定了你写驱动时要不要背一致性这个包袱。凡是碰DMA、碰多核共享数据、碰外设共享缓冲的代码都要把缓存一致性命中规则刻在脑子里。5. 各类存储的核心差异对照表与选型决策5.1 关键维度横向对比把前面内容压缩成一张表方便随时对比存储类型典型访问延迟典型容量易失性单位成本功耗特征主要用途寄存器堆0.2-0.5ns几十到几百B易失最高极低CPU运算临时数据SRAM / TCM0.5-5ns几百KB-几十MB易失高静态漏电明显Cache、片内内存、实时数据DRAM / LPDDR50-100ns数百MB-数十GB易失需刷新中刷新功耗不可忽略系统主存NOR Flash80ns读1-64MB非易失中高读功耗低固件存储、XIP启动NAND / eMMC / UFSus-ms级含控制器开销GB-TB级非易失低大块读功耗高用户数据、操作系统镜像Boot ROM同SRAM几十KB-数MB非易失中极低启动固化代码eFuse / OTP慢读写过程特殊几B到几KB非易失不可改低极低密钥、ID、配置这张表反映的是典型量级具体数字会随工艺和代际变化但数量级关系几十年来没有本质改变。这种速度-容量-成本的三角约束是整个SoC存储设计的祖训。5.2 速度与功耗的现实博弈很多人忽略的一点是存储不只影响速度还直接主导功耗。SRAM静态漏电大容量越大、待机功耗越高所以手机SoC里大Cache必须配合电源门控不用时把对应的SRAM阵列断电。DRAM需要持续刷新进入自刷新模式后虽然功耗低了但访问延迟会进一步恶化。Flash/NAND在写入时要先擦除高压和电荷泵功耗都不小。UFS读写大量数据的时候峰值功耗也能到瓦级。所以在做功耗敏感的SoC设计时存储策略不是越快越好而是够用就好。一个经典决策如果待机时大部分时间只需要保持几十KB的上下文那就让DRAM进自刷新、让大Cache整体断电只保留一小块SRAM和Boot RAM维持状态。这一步优化在手机SoC的续航表现里作用非常大。看手机天梯图和电池测试时你也可以注意一下同样性能和调度下存储子系统的功耗控制决定了热度与续航。5.3 存储选型的决策模型把前面的知识折叠成一个实用的选型流程当你要给一块功能模块选存储时可以按这个顺序过数据是否断电后还要保留要保留直接走向Flash族不要保留看下一步。是否要求确定性延迟要求确定、而且代码和数据不允许有未命中风险走向TCM/片内SRAM。容量是否超过几MB超过必须走向DRAM没超过可以考虑SRAM/tightly coupled RAM。是否需要频繁就地执行代码需要XIP选NOR Flash否则NAND/UFSeMMC拷贝执行。是否是安全信任根放进eFuse/OTP或者受保护ROM区域。这个流程看起来朴素但支撑了大量SoC子系统的存储选型。我每次给模块定存储方案时都按这个框架过一遍很少出大错。核心就一句话先看数据生命周期再看时序要求最后才看容量和成本。6. 从手机SoC天梯图到启动链路存储如何决定真实体验6.1 手机SoC的片内片外存储切割用一颗典型手机SoC的存储布局来收拢前面所有概念CPU簇内部是L1和L2 CacheSRAM簇与簇之间共享一个较大的L3 CacheSRAM个别SoC用eDRAM实现然后通过内存控制器挂多通道LPDDR主存通过UFS控制器挂大容量闪存而启动和安全校验的前两跳落在Boot ROM和eFuse里。这里有一个很多人看天梯图时容易忽略的点片内Cache决定的是瞬时爆发性能片外DRAM带宽决定的是持续吞吐性能UFS速度决定的是应用安装和加载体验。如果一个SoC的CPU堆得很猛但内存控制器位宽只有32bit、UFS只支持老协议那么跑分时帧率可能还行一进大型游戏场景、加载应用、解压文件就会原形毕露。真正懂看门道的人会更关注内存带宽、UFS版本、Cache容量和一致性互连的效率这些存储相关参数。6.2 一次从Boot ROM到App的完整启动路线图我把一个典型系统上电后的存储角色巡礼写在这里这也是SoC芯片启动这个话题的落地版上电复位CPU从固定地址取指该地址落在Boot ROM。Boot ROM是ROM内容固定。Boot ROM初始化基础时钟和堆栈读取启动引脚或eFuse里的配置确定从哪块Flash加载下一段。如果需要安全启动Boot ROM用eFuse里的根公钥验签Bootloader镜像镜像如果放在NOR Flash上可以直接从NOR读如果放在eMMC/UFS里则先初始化对应的存储控制器。Bootloader继续初始化DDR/LPDDR做DRAM训练并配置内存控制器。DDR训练是这一步的重头戏因为读写时序稍有偏差后面的系统就会跑出随机错误。操作系统内核从Flash介质加载到DRAM再由DRAM为进程、页表、缓存提供运行空间。应用运行时的关键热点代码和数据通过CPU的Cache层层命中只有未命中才回DRAM甚至回UFS。这条链路里每一站用的存储类型都不相同掉了任何一环都开不了机。理解了它你再去看SoC启动相关的代码和时序图就会觉得非常顺。6.3 存储验证相关工作的一点经验顺便说一下验证侧。热搜词里有验证开源存储相关验证在SoC验证里占据了很大比重你要验证Cache一致性协议、内存控制器在不同温度电压下的行为、Flash控制器的坏块管理、刷新和自刷新切换、以及eFuse的烧录保护逻辑。现在开源社区里能用的验证IP和参考模型越来越多比如各种UVM框架下的memory model、可配置的cache model。如果你是学生或者刚转行芯片验证建议从写一个简单的SRAM模型理解握手、再过渡到Cache一致性验证环境这样对SoC存储全貌的理解会比你对着PPT光看快得多。我自己带过的项目里存储验证的bug往往都不在功能正确性上而恰恰在性能边界和低功耗状态切换上——这是最吃经验的部分也是仿真最容易漏的地方。最后再分享一点我自己的体会。做SoC相关的开发也好、选型也好、写驱动也好别把存储当成一个个孤立的器件去看。一次关键数据流的延迟是寄存器、Cache命中率、DRAM带宽、Flash调度共同作用的结果。你可以在项目里先把数据从哪里来到哪里去、每一站延迟多少、命中率多少画成一条通路再决定优化哪一级。这比凭感觉换一个大Cache或者加高内存频率要靠谱得多。
返回列表