ARTICLE DETAIL

资讯详情

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

从晶体管到DIMM:深入解析DRAM内部结构与DDR4时序图

从晶体管到DIMM:深入解析DRAM内部结构与DDR4时序图 1. 从一颗晶体管说起为什么值得深挖DRAM内部结构很多人第一次接触内存是从“加根条子”开始的。买回来一条DDR4 DIMM插进主板开机完事。至于这条内存里面到底装了什么、为什么频率是2666而不是3200、为什么时序是CL19而不是CL16大多数人是不关心的。但如果你做过底层性能调优、写过内存敏感的代码或者单纯被“为什么DDR4默认频率是2666”这个问题卡住过那你迟早得把DRAM的内部结构翻个底朝天。这篇内容就是干这个的。我会从最底层的晶体管讲起一路推到DIMM模组的物理结构再把DDR4的时序图拆开揉碎讲清楚。核心关键词就几个DRAM、DIMM、DDR4、时序图、晶体管。适合谁看适合那些不满足于“插上能用就行”想知道内存条里面到底在发生什么的开发者、硬件爱好者和系统调优人员。读完你至少能明白三件事DRAM凭什么用一颗晶体管加一个电容就能存一个bit、DIMM上那些密密麻麻的走线是怎么组织的、以及DDR4的时序参数到底在约束什么。先说一个最朴素的认知DRAM的存储单元本质上就是一个晶体管加一个电容。晶体管当开关电容当存储介质。电容充满电代表1放完电代表0。就这么简单。但简单的东西要做到几十亿个集成在一块芯片上、还要在纳秒级别完成读写难度就完全不一样了。这也是为什么DRAM能成为现代计算机里性价比最高的主存介质而SRAM只能缩在CPU缓存里。我见过太多人把DRAM当成一个“黑盒”觉得反正有内存控制器管着自己不用操心。但实际调优的时候你不懂内部结构就不知道bank冲突为什么会让性能掉那么多不知道refresh为什么必须周期性插入不知道tRCD和tRP到底在等什么。所以下面我会一层一层往下拆从晶体管到存储阵列从阵列到bank从bank到rank从rank到DIMM最后落到DDR4的时序约束上。2. DRAM存储单元一颗晶体管加一个电容的极限艺术2.1 1T1C结构到底怎么存一个bitDRAM的存储单元叫1T1C也就是一个晶体管Transistor加一个电容Capacitor。晶体管是NMOS栅极接字线Word Line, WL漏极接位线Bit Line, BL源极接电容的一端电容另一端接参考电位通常是Vcc/2或者地取决于设计。写1的时候位线驱动到高电平字线拉高晶体管导通电容被充电。写0的时候位线拉到低电平字线拉高电容放电。读的时候稍微麻烦一点先把位线预充到一个中间电平比如Vcc/2然后拉高字线电容和位线之间发生电荷分享。如果电容里存的是1位线电压会略微上升如果存的是0位线电压会略微下降。这个电压变化非常小通常只有几十到几百毫伏所以需要**灵敏放大器Sense Amplifier**来检测并放大成全摆幅的逻辑电平。这里有个关键点读取是破坏性的。电荷分享之后电容里的电荷已经被扰动原来的数据不再可靠。所以每次读操作之后灵敏放大器必须把检测到的值重新写回电容这个过程叫恢复Restore。这也是为什么DRAM的读操作在时序上比写操作更复杂。注意1T1C结构的电容容量极小通常在20-30fF量级。这个电容必须在极小的面积内做到足够的容量同时漏电要足够小否则数据保持时间会短到无法接受。这也是DRAM工艺和逻辑工艺最大的区别之一——DRAM需要专门的深沟槽或堆叠电容工艺。2.2 为什么不能用SRAM替代DRAMSRAM的存储单元是6个晶体管6T不需要刷新速度也快得多。那为什么主存不用SRAM答案就一个字面积。6T单元的面积大约是1T1C单元的6到10倍。同样一块晶圆做SRAM只能做出DRAM几分之一的容量。主存需要的是大容量、低成本速度可以靠并行和缓存来补。所以SRAM退守到CPU缓存DRAM统治主存这是成本和性能权衡的必然结果。但DRAM的代价也很明显需要周期性刷新。电容会漏电数据保持时间通常只有几十毫秒。JEDEC标准规定DDR4在85°C以下时刷新周期是64ms也就是说每64ms内必须把所有行都刷新一遍。温度越高漏电越快刷新周期要相应缩短。这就是为什么高温环境下内存稳定性会下降——不是内存坏了是电容漏电太快刷新来不及。2.3 从晶体管到存储阵列行和列的组织方式单个存储单元没有意义必须组织成阵列。DRAM的存储阵列是二维的行Row和列Column。行由字线控制列由位线控制。一个阵列通常有几千行和几千列具体数量取决于工艺和设计。访问一个单元需要两步先激活整行把字线拉高把这一行所有单元的数据都读到灵敏放大器里然后再通过列选择信号从灵敏放大器里选出目标列的数据输出。这就是为什么DRAM的访问延迟分为行激活延迟tRCD和列访问延迟CL两部分。行激活是慢操作因为要驱动一整条字线还要等灵敏放大器完成放大列访问是快操作因为数据已经在灵敏放大器里了。这种“整行激活”的机制有一个重要后果同一行内的连续访问很快跨行访问很慢。这就是行缓冲命中Row Buffer Hit和行缓冲缺失Row Buffer Miss的概念。如果连续访问的地址落在同一行后续访问只需要列切换延迟很低如果落在不同行就需要预充当前行、激活新行延迟大幅增加。这也是为什么内存访问模式对性能影响巨大——顺序访问通常比随机访问快得多。3. 从阵列到Bank并行度是怎么堆出来的3.1 Bank的划分与交错访问一个DRAM芯片内部不会只有一个阵列而是有多个Bank。每个Bank有自己的灵敏放大器和行缓冲可以独立进行行激活和预充。Bank的存在是为了提高并行度当一个Bank在预充或刷新时另一个Bank可以进行读写从而隐藏延迟。DDR4通常有16个Bankx4/x8颗粒或8个Bankx16颗粒分为4个Bank Group。Bank Group的引入是DDR4相对DDR3的一个重要改进同一Bank Group内的Bank共享一些时序约束不同Bank Group之间的时序约束更宽松从而提高了交错访问的效率。访问不同Bank的地址可以交错进行内存控制器会把物理地址映射到不同的Bank、Rank和Channel上以最大化并行度。这个映射策略叫地址交错Address Interleaving通常以Cache Line64字节或更大的粒度进行交错。交错粒度太小会导致频繁的Bank冲突太大则并行度不够。实际系统中这个映射是内存控制器和BIOS共同决定的调优空间有限但理解它对分析性能问题很有帮助。3.2 Rank和ChipDIMM上的多颗颗粒怎么协同一个Rank是一组被同一组片选信号CS控制的DRAM芯片它们共同组成一个逻辑上的宽端口。比如一个64位数据宽度的Rank可以由8颗x8的DRAM芯片组成每颗提供8位数据。DIMM上通常有1到2个Rank服务器DIMM可能有4个甚至更多。Rank的概念很重要因为同一Rank内的芯片必须同步操作而不同Rank之间可以部分并行。切换Rank需要额外的时序开销tRRS、tRRD等所以频繁跨Rank访问会降低效率。内存控制器会尽量把访问集中在同一Rank内但容量越大Rank越多跨Rank访问的概率也越高。DIMM的物理结构就是把这些Rank和Chip焊在一块PCB上加上金手指、SPD芯片和必要的电阻电容。SPDSerial Presence Detect是一颗EEPROM里面存了DIMM的容量、速度、时序参数等信息BIOS启动时通过SMBus读取SPD来配置内存控制器。如果你改过SPD就知道这东西有多重要——改错了直接开不了机。3.3 为什么DDR4默认频率是2666这个问题我被问过很多次。DDR4的JEDEC标准频率从2133起步到3200为止。但市面上大量DDR4条子的默认频率是2666而不是3200。原因有几个第一JEDEC标准里2666是主流速度 bin。DDR4-2666对应的时序通常是CL19而DDR4-3200对应CL22。从颗粒厂商的角度2666的良率更高成本更低。第二内存控制器的默认配置。很多主板和CPU的默认内存频率就是2666因为这是平台验证过的稳定点。第三XMP/DOCP需要手动开启。你买了一条3200的条子插上去默认跑2666是因为XMP没开。开了XMP之后主板会读取SPD里的XMP profile把频率和时序拉到3200。但XMP不是JEDEC标准稳定性取决于CPU内存控制器的体质和主板布线。所以“DDR4默认频率2666”不是技术限制而是标准、成本和默认配置共同作用的结果。你想跑3200开XMP就行但要做好可能不稳定的准备。4. DDR4时序图详解那些纳秒级的等待到底在等什么4.1 核心时序参数逐个拆解DDR4的时序参数是一组以时钟周期为单位的数值通常写成CL-tRCD-tRP-tRAS的形式。下面这张表把最核心的参数列出来参数全称含义典型值DDR4-2666CLCAS Latency列地址选通延迟从读命令到数据输出的时钟数19tRCDRAS to CAS Delay行激活到列访问的延迟19tRPRow Precharge预充时间关闭当前行到可以激活新行19tRASRow Active Time行激活最短保持时间43tRCRow Cycle Time行周期时间tRAS tRP62tRFCRefresh Cycle Time刷新周期时间350-560tRRDRow to Row Delay不同Bank间行激活的最小间隔4-6tFAWFour Activate Window四个行激活的时间窗口16-34这些参数的单位都是时钟周期实际时间要乘以时钟周期。DDR4-2666的时钟频率是1333MHz周期约0.75ns。所以CL19的实际延迟是19 × 0.75 ≈ 14.25ns。加上tRCD和tRP一次完整的行缺失访问延迟大约是CL tRCD tRP ≈ 42.75ns。这还没算内存控制器的调度延迟和信号传播延迟。4.2 读操作的完整时序流程一次读操作如果发生行缺失完整流程是这样的预充Precharge如果目标Bank有打开的行先发预充命令等待tRP。行激活Activate发激活命令选中目标行等待tRCD。读命令Read发读命令选中目标列等待CL。数据输出Data Burst数据在DQ总线上以突发形式输出DDR4的突发长度通常是8BL8。恢复Restore灵敏放大器把数据写回电容这个和读命令重叠进行。如果发生行命中步骤1和2可以省略直接发读命令延迟只有CL。这就是为什么行命中率对性能影响巨大。时序图上你可以看到CK_t/CK_c差分时钟、CS_n片选、ACT_n激活、RAS_n/CAS_n/WE_n命令编码、地址总线、以及DQ数据总线。关键的时间关系是ACT_n拉低后地址总线上的行地址被锁存tRCD之后CAS_n拉低列地址被锁存CL之后DQ上出现有效数据。注意DDR4的地址总线是复用的行地址和列地址分时传输。ACT_n期间传行地址读/写命令期间传列地址。这也是为什么tRCD必须存在——地址总线需要时间切换。4.3 写操作的时序差异写操作和读操作最大的区别是写数据是和写命令同时发出的而不是等CL之后。DDR4的写延迟CWL, CAS Write Latency通常比CL小因为写数据不需要经过灵敏放大器检测直接驱动电容就行。但写操作需要额外的写恢复时间tWR确保电容充电完成之后才能预充。写操作的时序流程预充如果需要→ 行激活 → 等待tRCD → 发写命令和写数据 → 等待tWR → 预充。写操作没有CL但有CWLCWL通常等于CL-1或CL-2取决于频率。4.4 刷新操作对时序的影响刷新是DRAM不可避免的开销。DDR4的刷新有两种模式自动刷新Auto Refresh和自刷新Self Refresh。自动刷新由内存控制器发起每次刷新一行所有Bank同时刷新。刷新期间内存不能响应读写请求所以刷新会直接吃掉带宽。tRFC是刷新周期时间DDR4-2666的tRFC大约是350ns相当于466个时钟周期。在这段时间里内存完全不可用。如果刷新频繁发生性能会明显下降。这就是为什么高温下性能会掉——刷新周期从64ms缩短到32ms甚至更短刷新开销翻倍。实操心得在性能敏感的场合可以通过调整刷新模式来优化。比如把自动刷新改为细粒度刷新Fine Granularity Refresh把一次大刷新拆成多次小刷新每次刷新时间更短对延迟敏感型负载更友好。但细粒度刷新的总开销略高适合延迟敏感而非带宽敏感的场景。5. 从DIMM到系统物理结构如何影响实际性能5.1 DIMM PCB布线与信号完整性DIMM的PCB不是随便画的。DDR4的信号速率到了2666MT/s甚至3200MT/s信号完整性成了大问题。DIMM上的走线必须做阻抗控制通常单端信号50欧姆差分信号100欧姆。走线长度要匹配同一组信号的走线长度偏差要控制在几个mil以内否则会出现时序偏斜Skew导致采样错误。DIMM通常采用Fly-by拓扑地址、命令、控制信号从金手指进入后依次经过每颗DRAM芯片末端做匹配端接。数据信号则是点对点每颗芯片到内存控制器的走线长度要匹配。这种拓扑对DDR4的高速信号是必要的但也带来了写入均衡Write Leveling的需求——内存控制器需要调整每颗芯片的写数据延迟补偿Fly-by拓扑带来的时钟偏斜。5.2 SPD与内存训练SPD里面存了DIMM的时序参数但实际运行时内存控制器还需要做内存训练Memory Training。训练包括读训练、写训练、命令训练等目的是找到最佳的采样点和延迟设置。训练过程在BIOS启动时进行通常几百毫秒到几秒不等。训练不充分会导致开机不稳定或性能下降。如果你遇到过“开机反复重启几次才能点亮”的情况大概率是内存训练在反复尝试。训练结果会保存在BIOS里下次启动直接使用。清除CMOS会丢失训练结果下次启动又要重新训练。5.3 多通道与交错对带宽的影响现代平台通常支持双通道或四通道内存。多通道的本质是增加内存控制器的位宽从而线性提升带宽。双通道DDR4-2666的带宽是2666 × 8字节 × 2 42.6GB/s。四通道就是85.3GB/s。但多通道的带宽提升不是自动的需要地址交错把访问均匀分布到各个通道上。如果交错策略不好或者访问模式太集中多通道的带宽优势就发挥不出来。实际测试中双通道相对单通道的带宽提升通常在70%-90%之间而不是理想的100%就是因为交错和调度开销。6. 常见问题与排查技巧实录6.1 内存不稳定怎么排查内存不稳定的表现很多蓝屏、程序崩溃、数据损坏、开机失败。排查思路是从软到硬、从易到难现象可能原因排查方法开机反复重启内存训练失败降频、放宽时序、换插槽跑测试报错颗粒或时序问题跑MemTest86逐条测试高负载蓝屏供电或散热问题检查VCCSA/VCCIO电压加风扇随机数据损坏信号完整性问题降频、调整ODT和驱动强度高温下不稳定刷新不足改善散热降低环境温度我踩过最坑的一次是一条3200的条子开XMP跑3200没问题但跑MemTest86到第7轮开始报错。降到3000就稳了。后来查出来是CPU内存控制器的体质问题不是条子的问题。所以内存稳定性是CPU、主板、条子三者共同决定的不能只怪条子。6.2 时序参数怎么调调时序的顺序很重要。先调频率再调CL再调tRCD和tRP最后调tRAS和tRFC。每次只调一个参数调完跑稳定性测试。tRFC对性能影响很大但调太紧容易出错。tFAW和tRRD影响Bank间并行度调紧可以提升随机访问性能但太紧会导致Bank冲突增加。实操心得DDR4的tRFC和温度强相关。高温下tRFC需要放宽否则刷新不完整会导致数据丢失。如果你在高温环境下跑内存密集型负载建议把tRFC放宽10%-20%稳定性会好很多。6.3 为什么DDR4读写测试结果和理论带宽差那么多理论带宽是频率 × 位宽但实际带宽受限于很多因素刷新开销约3%-5%、行激活开销、Bank冲突、读写切换开销、内存控制器调度效率。实际带宽通常是理论带宽的60%-80%。如果低于60%说明访问模式有问题或者时序太松。用STREAM或Intel MLC测试内存带宽时要注意测试的访问模式。顺序访问的带宽最高随机访问的带宽可能只有顺序访问的几分之一。如果你的应用是随机访问密集型优化方向应该是提高行命中率而不是一味提高频率。6.4 DRAM测试工具怎么选MemTest86是最常用的内存测试工具跑完整测试需要几个小时。HCI MemTest可以在Windows下跑适合快速筛查。TestMem5配合特定配置文件可以测出一些MemTest86测不出的问题。Linux下可以用memtester。对于硬件层面的测试需要用到逻辑分析仪或示波器抓时序图这就不是软件工具能搞定的了。我个人习惯是新条子上机先跑MemTest86一轮没问题再跑TestMem5的1usmus配置文件三轮。都过了才认为稳定。如果报错先降频再放宽时序逐步定位问题。7. 写在最后一些零散的经验DRAM这东西越挖越深。从晶体管到DIMM每一层都有大量的设计取舍和工程细节。我写这篇内容的时候尽量把最核心的链路讲清楚但肯定还有很多没覆盖到的地方比如Bank Group的具体时序约束、ODT和驱动强度的调整、以及DDR5的新特性。如果你只是想解决“为什么我的DDR4默认2666”这个问题那答案很简单开XMP。但如果你想真正理解内存的行为那时序图是绕不过去的。我建议你找一份DDR4的JEDEC标准对着时序图把读、写、刷新三种操作的流程走一遍比看任何二手资料都管用。最后分享一个我常用的调试方法当你怀疑内存有问题时先把频率降到2133时序放到最松跑测试。如果还报错那就是硬件问题如果不报错再逐步往上调找到稳定边界。这个方法虽然笨但能帮你快速区分是硬件故障还是参数问题。
返回列表