ARTICLE DETAIL

资讯详情

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

DRAM刷新机制详解:集中式、分散式与异步式如何取舍

DRAM刷新机制详解:集中式、分散式与异步式如何取舍 做模型机课设的时候存储器那块经常会被问到一个问题教材上花了一整节讲 DRAM 的刷新还拆成集中式刷新、分散式刷新、异步式刷新三种可我板子上的存储器压根不涉及这些那这节内容到底在讲什么说实话这个问题背后藏着一个更根本的困惑——很多人是先把三种刷新的定义背下来了却从来没想清楚刷新这件事在硬件层面到底是怎么发生的为什么会有三种不同的组织方式以及它们各自在算计什么。我自己当年在 408 的计组里第一次接触这块内容时也是把三个名词混成一团做题全凭感觉直到后来自己动手搭过一遍存储器时序才把这里面的账算明白。这篇就把这件事从头捋一遍DRAM 为什么必须刷新一次刷新具体做了什么动作然后分别看集中式、分散式和异步式三种方案各自在时间和控制上付出了什么代价最后落到课设和考试里最容易踩的坑上。不管你是正在啃 408 计组还是在做带存储器的模型机课设希望能帮你把这三种刷新方式真正区分开而不是停留在背名词的层面。1. DRAM 到底为什么要刷新电容漏电和破坏性读出的双重压力1.1 SRAM 不用管DRAM 必须管根子在存储单元的结构要理解刷新得先回到存储元件的物理实现上。SRAM 的存储单元是双稳态触发器由六个晶体管组成只要不断电两个稳定状态就能一直保持写进去的 0 和 1 不会自己跑掉所以 SRAM 完全不需要刷新。DRAM 就不一样了它的存储单元本质上是一个晶体管加一个电容信息以电荷的形式存在电容上——电容上有电荷表示 1没电荷表示 0。问题在于这个电容的容量极小通常只有几十飞法而晶体管存在微弱的漏电流电荷会慢慢漏掉。如果不管它几毫秒之内信息就全丢了。所以 DRAM 的刷新不是可选优化而是不刷新直接不能用。这一点决定了刷新电路是存储器系统里绕不开的一环也是为什么教材要单独用一节来讲它。很多同学一开始会觉得刷新是某种额外的性能优化手段其实完全相反它是 DRAM 能正常工作的前提条件。1.2 刷新以行为单位一次刷新一整行这里有个非常关键、又特别容易被忽略的点DRAM 的存储阵列是行列矩阵结构刷新不是一个个单元去刷而是按行刷。DRAM 内部有行缓冲读出放大器组选中一行之后整行的信息会被同时读出到读出放大器上然后由读出放大器再写回原来的电容里。这个过程既完成了恢复被破坏的信息也顺带完成了刷新。所以一次刷新操作覆盖的是一行里的所有存储单元行内是并行处理的。这就解释了为什么刷新时间的计算里分子永远是行数而不是存储单元总数或者字数。比如一个 128×128 的存储矩阵刷新一遍需要刷 128 次而不是 128×12816384 次。搞不清这一点后面的所有计算都会错。1.3 刷新周期和存取周期根本不是一回事教材里有两个词长得像、意思完全不同的概念必须分清楚。第一个是存取周期也叫存储周期指的是 CPU 完成一次读或写所需的时间包含地址建立、数据读出/写入以及必要的恢复时间典型值比如 0.5μs。第二个是刷新周期指的是整个芯片要求所有行必须刷一遍的时间上限典型值比如 2ms。这两个时间差了三个数量级绝不是一个东西。还有一种容易混淆的说法是把刷新周期和刷新间隔搞混。刷新间隔是每隔多久刷一行它等于刷新周期除以行数刷新周期是刷完所有行的总时限。在异步式刷新里15.6μs 是刷新间隔2ms 是刷新周期两者不能互换使用。做题的时候只要题干给出刷新周期 2ms你就知道这是所有行刷一遍的总时限剩下的动作就是拿它去除行数。另外顺便说一句刷新和重写再生也不是一回事。重写是破坏性读出之后的恢复动作它属于一次正常访存流程的组成部分而刷新是定时的、与 CPU 当前访问哪个地址无关的、由刷新控制器发起的独立操作。刷新地址来自刷新计数器不占用 CPU 给出的地址。2. 集中式刷新一次刷干净的爽快与那段死时间2.1 集中刷新的动作顺序前面正常跑末尾一口气刷完集中式刷新的思路最直白在每一个刷新周期比如 2ms内先让 CPU 正常访存等到周期快结束的时候集中拿出一整段时间把所有的行依次刷一遍。这段时间内存储器不响应任何来自 CPU 的读写请求一整段被征用了业内把这称为访存死区或者死时间。具体到 128×128 的芯片、存取周期 0.5μs 的典型参数刷新一遍需要 128 次行刷新每次占一个存取周期 0.5μs所以死时间就是 128 × 0.5μs 64μs。也就是说每 2ms 里有 64μs 是 CPU 完全不能碰存储器的其余 1936μs 可以随意访存。2.2 死时间占比和它对系统的影响64μs 听上去不长但放到整个刷新周期里算一下占比64μs / 2000μs 3.2%。这个数字本身不算高但它有个致命的特点——集中。如果 CPU 恰好在这个时间窗口里要取指令或者读写数据只能停下来等等满 64μs。假设 CPU 本身一条访存指令的周期是 0.5μs那这 64μs 相当于 128 个访存周期被生生吞掉若程序正好在密集访存性能抖动会非常明显。集中刷新的另一个特点是控制逻辑非常简单。因为它只需要一个计数器数到某个点就触发一次批量刷新中间不需要和 CPU 的访存请求做复杂仲裁。这也是它在早期一些简单系统里还能见到身影的原因。但它对实时性要求高的场景很不友好因为最坏情况下的访存延迟被拉长到了 64μs 这个量级。2.3 集中刷新适合什么、不适合什么从工程角度看集中式刷新适合那些能容忍周期性停顿的场合。比如某些图像处理或者批量数据搬运场景访存是成批进行的只要把刷新时段安排在批次之间的空隙就能把影响摊薄。它也很适合教学因为它把刷新开销这个概念用最极端的方式暴露出来方便学生理解死时间到底意味着什么。但如果系统里有对延迟敏感的操作比如实时中断响应、高速缓存未命中后的补行集中式刷新就是明显的短板。另外还有一个隐含问题如果刷新周期被压缩比如温度升高导致电容漏电加快需要更短的刷新周期死时间会随之变得更频繁系统的平均性能会进一步下降。这个压力在异步式方案里会被摊平但在集中式方案里会原样放大。3. 分散式刷新塞进每个存取周期的刷法为什么反而更亏3.1 分散刷新的机制一个存储周期拆成两半分散式刷新换了个思路它不搞集中爆发而是把刷新动作平摊到每一次访存里。具体做法是把一个存储周期分成两半前半段用来完成 CPU 的读写访问后半段用来刷新一行。这样一来任何时刻都不会出现连续一大段不能访存的情况从字面上看似乎消灭了死时间。但代价立刻体现在存储周期上。原本 0.5μs 的存取周期加上 0.5μs 的刷新时间整个存储周期变成了 1μs也就是翻了一倍。这意味着 CPU 每做一次访存就要多花一倍的时间。系统整体速度直接被拖下来了。教材上说的无死区但降低了整机速度指的就是这个。3.2 算一笔账分散刷新其实刷得远远过勤更值得琢磨的是分散刷新的刷新频率高得离谱。还是 128 行的芯片每个存储周期刷一行那么刷完所有 128 行只需要 128 个存储周期也就是 128 × 1μs 128μs。而芯片的真实要求是 2ms 内刷一遍就行这意味着分散刷新把刷新频率提高了大约 2000μs / 128μs ≈ 15.6 倍做了十几次完全没必要的刷新。这就是分散刷新最反直觉的地方它看起来最安全、最均匀、最不打扰 CPU实际上它把刷新开销放大了一个数量级还额外把存储周期翻倍等于双重浪费。很多同学第一次看到分散刷新没有死时间就默认它是最优解这正是最典型的理解偏差。3.3 存储周期翻倍这件事为什么杀伤力这么大把存储周期从 0.5μs 拉到 1μs不只是慢一点的问题它会顺着存储层次往下传导。CPU 的访存指令执行时间、cache 的缺失代价、总线的传输效率全都是按存储周期来算账的。存储器慢了整整一倍整个系统的 CPI 都会被拉高。所以分散式刷新在真实系统里几乎不会单独使用它更像是一个教学对照项——用来告诉你为了消灭死时间而牺牲存储周期这条路走不通。它真正的价值在于引出第三种方案既不要把刷新攒成一大块也不要在每次访存里都刷而是按一个恰当的固定节奏来刷。4. 异步式刷新把刷新摊平到刷新周期里的折中方案4.1 15.6μs 这个数是怎么推出来的异步式刷新有的教材叫混合式刷新的思路是既然要求是2ms 内把 128 行刷一遍那就别攒着也别刷太勤干脆把 2ms 平均分成 128 份每份刷一行正好在时限内刷完一份不多一份不少。算出来就是 2000μs / 128 15.625μs。也就是说每隔大约 15.6μs存储器就拿出 0.5μs 刷一行剩下的 15.125μs 继续响应 CPU 的访存。死时间没有消失但被切成了 128 个 0.5μs 的小块最大连续不可访存时间从 64μs 骤降到 0.5μs。对 CPU 来说最坏情况下的等待从一整个 64μs缩短到了一个存取周期体验完全不同。4.2 总开销和集中式一样但分布完全不同这里有个很有意思的结论异步式刷新的总刷新时间开销和集中式是相同的都是 128 × 0.5μs 64μs。因为它们要刷的行数一样每行耗的时间也一样只是把这些时间什么时候用的排布方式换了。集中式把 64μs 攒成一段异步式把它拆成 128 段。所以异步式刷新真正优化的不是总开销而是开销的分布。它把开销均匀化让单次的最坏延迟可控同时也保证刷新频率刚好卡在需求线上不多刷一次。这才是它的核心价值。如果你做题时看到异步式刷新减少了刷新总时间这种说法那肯定是错的它减少的是最大单次停顿时间。4.3 控制回路要怎么搭定时器、刷新请求与仲裁实现异步刷新的硬件比集中式复杂一些。大致需要三样东西一个定时计数器用来产生 15.6μs 这个固定间隔一个刷新请求信号间隔一到就拉高一套仲裁逻辑判断当前是让 CPU 访存还是让路给刷新。通常刷新请求的优先级会高于 CPU 的普通访存请求因为刷新有硬性时限一旦错过就可能丢数据而 CPU 请求晚一拍通常只是性能问题。下面这段 Verilog 片段描述的就是这种异步刷新的定时与仲裁骨架假设时钟 100MHz周期 10ns把 15.625μs 除以 10ns 得到计数值 1562即每 1562 个时钟发一次刷新请求刷新时拉高 access_stall 让访存暂停module refresh_ctrl ( input wire clk, input wire rst_n, input wire access_req, // CPU 访存请求 output reg access_stall, // 高电平表示让 CPU 等一拍 output reg [6:0] ref_row, // 7 位行地址对应 128 行 output reg ref_req ); localparam CNT_MAX 1562; // 15.625us / 10ns 1562.5取 1562 reg [10:0] cnt; always (posedge clk or negedge rst_n) begin if (!rst_n) begin cnt 11d0; ref_req 1b0; access_stall 1b0; ref_row 7d0; end else begin if (cnt CNT_MAX) begin cnt 11d0; ref_req 1b1; end else begin cnt cnt 11d1; ref_req 1b0; end // 刷新请求优先CPU 访存让路 if (ref_req || access_stall) begin access_stall 1b1; ref_row ref_row 7d1; // 循环刷完 128 行 end else if (!access_req) begin access_stall 1b0; end end end endmodule这段代码只是示意刷新节奏怎么产生真实工程里还要接上 DRAM 的行地址锁存、行列选通等时序信号并且要注意刷新完一行后必须留出恢复时间才能发起下一次操作。把这段和教材里的三种刷新方式对照着看你会更容易理解为什么异步式刷新在控制复杂度和性能之间拿到了一个不错的平衡。5. 三种刷新方式摆在一起看死时间、存取周期、控制复杂度的账5.1 用一张表把差异钉死参数统一取 128 行、存取周期 0.5μs、刷新周期 2ms三种方式的对比对比项集中式刷新分散式刷新异步式刷新刷新节奏每个刷新周期末尾集中刷完每个存储周期刷新一行每 15.6μs 刷新一行单次最大不可访存时间64μs0.5μs但每周期都有0.5μs存储周期0.5μs 不变拉长为 1μs0.5μs 不变刷完一遍实际耗时64μs128μs刷得过勤2000μs刚好卡线刷新总开销64μs / 2ms存储周期翻倍 过度刷新64μs / 2ms控制复杂度低低中等主要缺点存在长死区拖慢整机速度仲裁逻辑较复杂从表里可以看出一个很清晰的定位集中式拿长死区换简单分散式拿整机速度换无长死区异步式则用一点控制复杂度换来了最均衡的结果。三者的取舍方向完全不同这也解释了为什么真实系统几乎都选异步式的思路。5.2 为什么总有人把分散和异步弄混这两个最容易混。记忆的关键是看刷新动作绑在谁身上。分散刷新的刷新绑定在每一次访存上CPU 每访存一次就顺带刷一行刷新周期等于存储周期乘以行数所以刷得特别勤。异步刷新的刷新绑定在定时器上定时器到点了才刷和 CPU 访存次数无关刷新间隔等于刷新周期除以行数。换个说法分散刷新是被动跟着访存走异步刷新是主动按时间走。抓住这个本质做题时看到每隔固定时间刷一行就知道是异步看到每个存取周期刷一行就知道是分散不会再看错。5.3 一句话说清三者各自的算盘集中式在算控制简单的账愿意接受一段集中停顿分散式在算消除长死区的账代价是拖长存储周期并严重过度刷新异步式在算最坏延迟可控的账用定时器把刷新均匀铺开把总开销控制在刚好满足要求的水平。想清楚每种方案在拿什么换什么比死记定义有用得多。6. 落到课设和模型机上这套刷新电路什么时候才真的需要6.1 用 SRAM 或片内 BRAM 时刷新根本不在你的考虑范围做基本模型机课设的时候绝大多数人用的是 FPGA 内部的 Block RAM或者外挂一片 SRAM 作为主存。这两种存储器都是静态的不存在电容漏电问题也就不需要任何刷新电路。我见过不少同学因为刚看完刷新那一章回去就给模型机加了个刷新计数器结果发现根本接不上反而把读写时序搞得一团乱。这里必须强调刷新是 DRAM 的专属需求你用的是 SRAM 或片内 RAM就完全不用管它。那为什么教材还要花这么多篇幅讲因为真实的计算机主存用的是 DRAM容量大、成本低而教材要教你的是真实系统里会遇到什么。模型机课设用 SRAM 是为了简化实现不是因为它更典型。理解这一点你就不会把课设的经验误当成通用结论。6.2 真接 DRAM 时刷新通常由控制器 IP 负责如果你在更完整的平台上接的是 SDRAM 或 DDR 这类动态存储器刷新基本不用你手工搭三态机。厂商或工具链会提供一个存储器控制器 IP里面已经实现了自动刷新逻辑你只需要在寄存器里配置刷新间隔参数比如常见的 tREFI就行。这个参数的含义恰好对应我们前面说的刷新间隔配得太小会浪费带宽配得太大有丢数据风险所以它的取值一般来自芯片数据手册不能随便拍脑袋。从这个角度看教材里的异步式刷新其实就是现代 DRAM 控制器自动刷新的简化模型。理解了 15.6μs 是怎么来的再看数据手册里的 tREFI就能明白那个数字背后的约束是什么。6.3 想在课设里验证刷新逻辑可以这么搭如果你确实想动手验证一遍刷新时序比较靠谱的做法是用一个计数器模块产生固定间隔的刷新请求再用一个简单的仲裁器决定这一拍是访存还是刷新然后用波形图观察 access_stall 的拉高节奏。重点看两个现象一是相邻两次刷新的间隔是否稳定在设定值附近二是刷新期间访存请求是否被正确挂起并在刷新结束后恢复。只要你用的还是 SRAM这个实验就只能验证控制逻辑本身刷新动作对存储内容没有实际影响想看到真实效果就得换成真正的 DRAM 器件。7. 做题和课设里最容易算错的几个点7.1 先数行数再乘周期最后除刷新周期几乎所有刷新相关的计算题都可以套这个顺序第一步确定存储阵列有多少行第二步确定一次刷新占多长时间通常就是一个存取周期第三步确定刷新周期的总时限。集中式的死时间是行数 × 单次刷新时间异步式的刷新间隔是刷新周期 ÷ 行数分散式的刷新间隔是存储周期 × 行数。这几个公式不要混着用最好在草稿纸上把每一步的单位写清楚避免把 μs 和 ms 算错。7.2 别把刷新当成读一次再写一次的两倍时间刷新确实是读出并写回但它不是分两次独立操作来计时的。DRAM 的行缓冲读出放大器完成整行的读出和回写是一个连贯动作在时序上就按一个存取周期来算。如果把它算成两倍时间所有题目的答案都会翻倍。这一点我在最开始做题时也栽过后来对着时序图看了一遍才彻底记住。7.3 存储周期被拉长和刷新开销是两笔不同的账分散式刷新有两个独立的代价一个是存储周期翻倍一个是过度刷新。这两笔账要分开算不能合并成一个刷新开销。前者影响的是 CPU 每次访存的时间后者影响的是刷新的无效次数。如果你在答简答题把这两点都写出来得分会更完整。7.4 刷新优先级通常高于普通访存这是一个容易被忽视但很重要的判断。刷新有硬性时限错过可能丢数据访存请求晚一拍只是性能损失。所以在仲裁逻辑里刷新请求一般优先响应CPU 请求暂时挂起。这个原则不仅能解释异步刷新的设计也能帮你在设计自己的控制器时做出合理取舍。7.5 温度会改变刷新需求电容漏电速度对温度很敏感温度越高保持时间越短刷新周期就要相应缩短。这就是为什么一些芯片会有高温加倍刷新的机制在温度超过阈值时把刷新频率提高一倍。这个细节在标准教材里往往一笔带过但如果你将来真的要和存储器控制器打交道它是必须知道的——数据手册里给的刷新周期参数通常都是在特定温度条件下测出来的。最后分享一个我自己踩过的坑。当年做课设一直以为存储器那部分刷新是必做项折腾了好几天想给 SRAM 加刷新逻辑怎么都对不上时序。后来请教了师兄才反应过来我们板子上压根没有需要刷新的器件白忙一场。所以每次开始动手前先确认你手头这块存储器的类型是静态还是动态——这一个判断能省下你好几天的弯路。而考试里的那些刷新计算本质上就是这套物理约束的数学表达把行数、单次刷新时间、刷新周期这三个量理清三种刷新方式就不再是一团乱麻了。
返回列表