2. 内存带宽与延迟分析:DDR带宽计算、延迟模型、实际吞吐量测试方法
好,咱们进入第二章。内存带宽和延迟,这俩词儿做嵌入式的人天天挂嘴边。但说实话,真正能把它算清楚、测明白的人,不多。
我个人习惯,拿到一块新板子,第一件事不是跑应用,而是先把DDR的带宽和延迟摸透。为什么?因为后面所有性能优化的天花板,就在这里。你CPU再快,内存喂不饱数据,全是白搭。
2.1 DDR带宽计算:别光看理论峰值
先说说理论带宽怎么算。公式其实很简单:
带宽 = 时钟频率 × 数据位宽 × 每时钟传输次数 × 通道数
举个例子,DDR4-3200,64位总线,双通道:
- 时钟频率:1600 MHz(DDR是双倍速率,等效频率3200 MHz)
- 数据位宽:64 bit = 8 Byte
- 每时钟传输次数:2(上升沿和下降沿各一次)
- 通道数:2
算一下:1600 MHz × 8 Byte × 2 × 2 = 51.2 GB/s。这是理论峰值。
重点来了:理论峰值你永远跑不到。我在海思项目上实测,能跑到理论值的70%-80%就算优化得不错了。为什么?因为还有协议开销、刷新周期、bank冲突这些乱七八糟的东西。
实际有效带宽,我一般用这个经验公式:
有效带宽 ≈ 理论峰值 × 0.7 ~ 0.85
嗯,具体系数取决于你的访问模式。顺序读写能接近0.85,随机访问可能掉到0.5以下。
2.2 延迟模型:别被数据手册骗了
带宽重要,延迟更重要。尤其是对实时性要求高的场景,比如视频处理、音频流。
DDR的延迟,说白了由三部分组成:
- 命令延迟(tRCD):从发出行激活命令到列选通命令的时间
- CAS延迟(CL):从列选通到数据开始输出的时间
- 传输延迟:数据在总线上传输的时间
数据手册上给的CL值,比如CL=22,那是多少个时钟周期。换算成实际时间:
延迟时间 = CL × 时钟周期
DDR4-3200的时钟周期是0.625 ns,CL=22的话,CAS延迟就是13.75 ns。看着不高对吧?
注意:这只是芯片内部的延迟。实际系统延迟还要加上PCB走线延迟、片内互联延迟、缓存缺失惩罚。我在一个项目中遇到过,实际测量出来的延迟比数据手册大了3倍,查了半天发现是PCB走线等长没做好。
我建议你建立自己的延迟模型,至少包含这几项:
- DDR芯片内部延迟(来自数据手册)
- PCB走线延迟(约0.15 ns/inch)
- SoC内部内存控制器延迟(这个得问芯片厂商)
- 缓存缺失惩罚(取决于你的缓存策略)
2.3 实际吞吐量测试方法:动手测才是硬道理
理论算完了,模型建好了,最后还得动手测。我常用的测试方法有三种:
2.3.1 软件微基准测试
用memcpy或者自定义的读写循环,测量不同访问模式下的吞吐量。代码很简单:
// 顺序读测试示例
volatile uint32_t *buf = (uint32_t *)0x80000000;
uint64_t start = get_cycle_count();
for (int i = 0; i < 1024*1024; i++) {
temp = buf[i];
}
uint64_t end = get_cycle_count();
printf("顺序读带宽: %f MB/s\n", (4*1024*1024) / ((end-start)/freq));
我个人习惯测这么几种模式:
- 顺序读
- 顺序写
- 随机读(步长64字节、128字节、4KB)
- 随机写
- 混合读写(7:3比例)
小技巧:测之前一定要先预热缓存,不然第一次访问全是cache miss,测出来的数据不准。我一般先跑一遍同样的循环,再开始计时。
2.3.2 硬件性能计数器
海思芯片内部有性能监视单元(PMU),可以直接读出DDR控制器的实际带宽和延迟。这比软件测量准得多。
我记得在海思3559A上,通过读取PMU寄存器,能看到实时的DDR利用率、读带宽、写带宽、平均延迟。这些数据对调优太有用了。
// 伪代码:读取DDR性能计数器
uint32_t ddr_read_bw = read_pmu(PMU_DDR_READ_BW);
uint32_t ddr_write_bw = read_pmu(PMU_DDR_WRITE_BW);
uint32_t ddr_avg_lat = read_pmu(PMU_DDR_AVG_LATENCY);
2.3.3 实际应用场景测试
微基准测试只能反映理想情况。真正的问题,往往出现在实际应用中。
我曾经做一个4K视频解码的项目,微基准测试显示DDR带宽还有30%余量,但实际解码就是掉帧。后来用硬件计数器一看,发现是DDR的bank冲突太严重,导致有效带宽骤降。
所以我的建议是:
- 先用微基准测试摸清DDR的底
- 再用硬件计数器监控实际运行时的数据
- 最后针对瓶颈做优化
2.4 避坑指南
我曾经踩过的坑:
- 别信数据手册上的理想延迟,实际测出来可能翻倍
- DDR频率不是越高越好,频率高了延迟反而可能变大
- 多通道DDR要小心地址映射,不然带宽根本发挥不出来
- 测带宽时记得关掉DMA和其他外设,不然测的是共享带宽
好了,这一章就到这里。记住一句话:内存性能,测了才知道。下一章咱们聊聊DDR的调优实战,包括时序参数调整和地址映射优化。
公众号:蓝海资料掘金营,微信deep3321