4. DRAM调度基础:DRAM架构(DDR4/DDR5/LPDDR)、行缓冲策略、预充电与激活

各位同学,今天我们聊聊DRAM调度。说实话,很多做芯片的同学对DRAM的理解停留在「就是个存数据的大池子」。但如果你真的去调过QoS,你会发现——DRAM的脾气比你想的复杂得多。

我个人习惯把DRAM比作一个图书馆。你想想看,你要找一本书,得先走到对应的书架(激活行),然后从书架上抽出来(列访问),看完还得放回去(预充电)。这一套流程,就是DRAM调度的核心。

4.1 DDR4/DDR5/LPDDR:三代架构的演进

先说说这三代架构的区别。我在做上一款AI芯片时,DDR4还是主流,现在DDR5已经铺开了,LPDDR则在移动端大杀四方。

参数 DDR4 DDR5 LPDDR5
数据速率 1600-3200 MT/s 4800-6400 MT/s 3200-6400 MT/s
Bank数量 16 32(分两组) 8-16
预取宽度 8n 16n 16n
工作电压 1.2V 1.1V 0.5-0.9V
命令总线 单端 差分 单端

DDR5最大的变化是什么?我个人觉得是Bank Group的引入。DDR5把32个Bank分成两组,每组16个。这样做的好处是——你可以同时激活两个不同组的Bank,并行度直接翻倍。

我曾经在一个项目中,把DDR4的调度器直接搬到DDR5上,结果性能反而下降了。为什么?因为DDR5的Bank Group特性没利用起来,调度器还在串行处理。后来改了策略,把请求按Bank Group分散,吞吐量提升了30%。

核心要点:DDR5的Bank Group是性能关键。调度时尽量把请求分散到不同Group,别挤在一个Group里死磕。

LPDDR呢?它更注重功耗。LPDDR5有个叫「深度睡眠」的模式,功耗可以降到微瓦级。但代价是唤醒延迟很大——大概几百纳秒。如果你的系统频繁唤醒,性能会很难看。

4.2 行缓冲策略:命中就是王道

行缓冲(Row Buffer)是DRAM性能的命门。说白了,DRAM每次访问都要先打开一行,把数据读到行缓冲里。如果下一次访问还是同一行,那就直接命中,省掉激活时间。

我给你们算笔账:

  • 行命中:延迟约15-20ns
  • 行冲突(先预充电再激活):延迟约40-50ns
  • 行未命中(直接激活新行):延迟约30-35ns

你看,行命中和行冲突差了将近3倍。所以调度器的核心任务就是——尽量让访问落在同一行。

怎么做到?我分享几个实战经验:

  1. 地址映射要合理:把连续地址映射到同一行。我见过一个项目,地址映射没做好,导致连续访问都在不同行,性能直接腰斩。
  2. 利用Bank级并行:如果一个Bank正在预充电,赶紧去访问另一个Bank。别傻等着。
  3. 关闭策略要谨慎:DDR4默认是「自动预充电」,每次访问完就关闭行。但如果你知道下一笔访问还是同一行,手动关闭就是浪费。

小技巧:在调度器里加一个「行命中预测器」。如果最近几次都命中同一行,就别急着预充电,等一等。我试过,命中率能提高10-15%。

4.3 预充电与激活:时间就是金钱

预充电(Precharge)和激活(Activate)是DRAM最耗时的操作。激活需要打开一行,预充电需要关闭一行。这两个操作都不能被中断,而且有严格的时序约束。

DDR4的时序参数大概是这样:

参数 含义 典型值(DDR4-3200)
tRCD 激活到列访问 13.75ns
tRP 预充电时间 13.75ns
tRAS 激活到预充电最小间隔 32ns
tRC 两次激活最小间隔 45.75ns

嗯,这里要注意。tRAS这个参数经常被忽略。它规定了激活后至少要等多久才能预充电。如果你提前预充电,数据可能还没读完,那就出错了。

我曾经踩过一个坑:为了追求低延迟,我让调度器在读完数据后立刻预充电。结果发现某些场景下数据读出来是错的。查了半天,原来是tRAS没满足。从那以后,我每次写调度器都会把时序参数表贴在墙上。

警告:不要为了性能牺牲时序。DRAM的时序参数是物理限制,不是建议值。违反时序会导致数据损坏,而且很难复现。

再说说激活策略。我个人习惯用「提前激活」——在数据真正需要之前,先把行打开。比如,你正在处理第N行,调度器可以预测第N+1行,提前激活。这样当请求到来时,行已经准备好了。

但提前激活也有风险:如果预测错了,你白白浪费了激活时间和功耗。所以预测算法要保守一点,别太激进。

4.4 知识体系总览

下面这张图是我自己画的,把DRAM调度的核心逻辑串起来了。你们可以保存下来,写代码时对照着看。

DRAM调度核心逻辑 内存请求队列 调度决策:行命中?行冲突? 预测下一行 + Bank Group分配 行命中 → 直接读 行冲突 → 预充电+激活 行未命中 → 直接激活 DRAM命令执行(ACT/RD/WR/PRE) 反馈:命中率统计

这张图的核心逻辑就是:请求进来,先判断行命中情况,然后选择最优路径。别忘了最后一步——反馈。把命中率统计出来,用来优化预测算法。

好了,DRAM调度的基础就讲到这里。记住三件事:行命中是王道,时序不能省,Bank Group要利用好。下一节我们聊聊更具体的调度算法,到时候我会拿实际项目的代码出来分析。

课后思考:如果你的系统里同时有DDR5和LPDDR5,调度器该怎么统一管理?两种架构的时序参数差异很大,你会怎么设计一个通用的调度框架?

专注资料整理