主存与DRAM
主存与DRAM
复习定位
内存(Dynamic Random Access Memory)的"动态"一词来自电容漏电的特性——每个存储单元是靠电容上的电荷量来保持0/1——电荷会随漏电消失。因此DRAM必须按规定频率周期性地读出再重新写入(刷新)。刷新期间内存无法被访问——设计者必须预开支这一开销。理解DRAM芯片的内部矩阵结构——行地址和列地址分时复用——是理解"为什么内存访问延迟随机不是固定的"来源。
DRAM存储单元——晶体管加电容的物理现实
DRAM的每个存储单元由1个晶体管+1个电容构成。字线(Word Line)控制晶体管的开关、位线(Bit Line)接在晶体管另一侧。写入时——字线拉高、晶体管导通——位线上的电压对电容充电。读出时——字线拉高——电容上储存的电荷通过晶体管流到位线——由灵敏放大器检测位线上极其微弱的——约30mV——电压变化并放大为0/1的数字电平。读出是破坏性的——电容上的电荷在读出过程中被释放——所以每次读操作后必须立即将刚读出的值写回(恢复)。
电容本身非常小——在当代纳米制程下单电容仅约十飞法——存储的电荷量约为几万个电子。电荷量越小——受α射线和宇宙射线影响翻转的几率越大——这是DRAM软错误(bit flip)的根本原因。服务器级ECC内存通过在每64位数据外附加8位校验码检测并纠正单bit错误——对内存的随机位错误提供了容错。
DRAM的漏电不可避免——通常在约64ms内电容会放电到无法确认0/1的电平水平。因此每个存储单元必须在64ms内被读出并写回一次(刷新)。DRAM内部每次刷新操作由刷新计数器自动遍历所有行——内存控制器每隔一段时间向所有芯片发送一条刷新命令——在此约70ns刷新期间内存不能响应正常读/写请求。刷新操作消耗DRAM带宽的约1%-2%。
DRAM芯片的矩阵结构
为什么DRAM地址不是一次全发完——而是分两次发送行地址(RAS, Row Address Strobe)和列地址(CAS, Column Address Strobe)——因为芯片的地址引脚数有限。地址引脚数减半对内存模组的小型化和兼容性非常重要。
DRAM芯片内部是一个二维矩阵——行地址选中一整行(Row)的所有存储单元——行数据被送到行缓冲区(Sense Amplifier Row Buffer)——约1KB到数KB。然后列地址从行缓冲区中选取若干bit输出。如果接下来的访问在同一行——可以直接在行缓冲区中读取——不需要重复激活行——省去tRCD时间。
现代DDR内存有多个Bank——每个Bank是一块独立的二维矩阵。多个Bank可以在不同行上并发操作——CPU读取bank1的行n时需要tRCD等待——在此期间bank2正在准备行m不需要冲突。CPU发出的行地址、bank地址和列地址共同确定内存访问的最终位置。
DDR的预取和突发传输
SDR(单数据率)内存每周期传1个数据——DDR(双)每周期传2个——DDR2每周期传4个——DDR3每周期传8个——DDR4/DDR5的预取队列长度进一步增加到8–16。预取队列通过在内存芯片内部使用更宽的I/O总线并行读取多个数据位来实现更高的每周期等效传输量——内存核心的时钟远低于I/O总线时钟——通过一次从核心层读出一个预取块再在高频I/O总线上分多次发送出去——实现等效高带宽的。
突发传输:一次请求从内存读一整条Cache Line(64字节)——DDR芯片在RAS+CAS后输出连续的突发数据——无需额外地址。DDR4也支持8n预取——一次读命令从其核心送出8个连续的64位字——正好是64字节(8×8Byte)的Cache Line——从而将单次内存访问的核心延迟隐藏在突发传输的串列节奏里。
内存访问时序参数量化
一次完整的DDR4读访问延迟 = tRCD(行选通到列选通) + CL(CAS延迟——列选到数据输出) + tRP(行预充电——关闭当前行)。典型DDR4-3200的tRCD=16个时钟、CL=22个时钟、tRP=16个时钟——总计54个时钟周期。3200MHz每个周期0.3125ns——54×0.3125≈16.9ns——再加上队列调度和系统总线延迟——实际应用中的典型内存负载延迟在60-100ns的区间。对4GHz的x86CPU来说——100ns等效于约400个时钟周期的等待——CPU只能执行其他指令或将线程挂起。
复习检查
DRAM的电容为什么必须周期刷新——如果超过64ms不刷新一个单元会发生什么——那存储的值还能恢复吗?
DDR4在每个时钟沿传输两次——它真正的内部核心时钟频率是多少?芯片外部的I/O总线和芯片内部阵列的工作频率相同吗?
内存的一次读请求为什么要先发RAS再发CAS——如果一次性发出完整的地址会有什么问题?
tRCD+tCL+tRP在DDR4-3200的典型约为54周期——换算为纳秒是多少——CPU在等待期间能做什么?
ECC内存每64位数据额外存储8位校验码——它可以纠正哪种bit错误?检测哪种bit错误?如果两个比特同时翻转(相邻行同时受到宇宙射线破坏)ECC会怎样?
DRAM芯片的物理结构详解
DRAM的核心是存储阵列——由无数个存储单元组成。每个存储单元是一个NMOS晶体管串联一个电容。字线连接到所有晶体管的栅极——控制开关——位线连接到所有晶体管的漏极——读/写数据。
写入过程——字线升高到高电压(Vcc)——晶体管导通——位线的电压通过晶体管对电容充电或放电——写入0或1。读出过程——字线升高——晶体管导通——电容上的电荷转移到位线——位线电压微弱变化(通常仅几十毫伏)——由灵敏放大器(Sense Amplifier)检测——放大到逻辑电平(0或1)。因为读取是破坏性的——读出后必须立即对电容重新充电以恢复。
灵敏放大器是DRAM的关键电路——它的速度直接决定了DRAM的访问速度。灵敏放大器将位线上的微弱差分信号放大——需要一定的时间(~10ns)才能稳定输出。这就是DRAM访问延迟较大的物理原因之一。
DRAM的刷新机制详解
每个DRAM行必须在64ms内被刷新一次——刷新一行大约需要约10ns。现代DRAM内部有一个刷新计数器——自动遍历所有的行——可以向芯片发送一条刷新命令(REF)——芯片自动对数个行执行刷新。
刷新操作的时序——芯片在收到刷新命令后——所有Bank同时对自己的一个行执行刷新——约需tRFC(Refresh Cycle Time)——对DDR4通常约350ns——在此期间整个芯片不能响应正常的读写操作。总的刷新开销约1-2%的带宽——但对于实时系统——刷新周期的时间不可忽略——在响应时间计算中要对此留出余量。
不同规格的DRAM的刷新间隔——温度越低漏电越小——部分工业级和汽车级内存支持在较低温度下延长刷新间隔(从64ms到128ms或256ms)——以减少刷新开销——但在高于85°C时必须使用更短的刷新间隔(通常为32ms)——否则数据会因漏电丢失。
DDR内存的预取与突发传输
DDR内存的核心时钟频率并非标称的速度等级名(如DDR5-4800的真正核心时钟仅为300MHz)——但因为它通过预取缓冲区一次从存储阵列读出8n(预取宽度)单位的数据——再通过高速I/O接口在外部时钟的上升沿和下降沿分别传输——使外部数据传输速率达到核心时钟频率的8倍以上。DDR5的预取深度为16n——一次从阵列读出16倍数据传输总线位数的数据——后通过高速SerDes接口从DIMM接口发送。
Cache Line(64字节)的读取——CPU发出读请求——内存控制器计算出Cache Line的起始地址——发送RAS(行激活)+CAS(列地址)命令——DRAM芯片内部将一整行数据(约1-2KB)读入行缓冲区——再从行缓冲区的指定列位置开始连续读取64字节的突发数据——一次内存读请求的实际传输数据量(DDR的突发长度8对应8个64位的传输——刚好64字节)正好覆盖一个Cache Line。
内存多通道架构
现代CPU支持双通道/四通道内存架构——将多条DDR通道组合在一起提供更高带宽。每个通道是独立的DDR接口——可以同时访问。
双通道——使用两条相同规格的内存条分别插入两个通道——理论上内存带宽翻倍。四通道(Intel Xeon/AMD Threadripper)——四个通道并行——进一步扩展带宽。内存通道在CPU的内存控制器内部独立——每个通道可以同时处理不同的请求——对于多核并发访问内存的负载(如数据库、虚拟机)——多通道配置的吞吐能力显著优于单通道。
但多通道对延迟的改善有限——它提高了总带宽——但单次访问的延迟仍然由单通道的DRAM内部参数决定(tRCD/tCL/tRP)。因此——对延迟敏感的应用(如高频交易)——提升CPU到内存的延迟比单纯增加通道数更重要。
内存错误校正——ECC与Chipkill
ECC(Error Correcting Code)内存在每64位数据上附加8位校验码——使用SECDED(Single Error Correct, Double Error Detect)方案——可以纠正1位错误——检测2位错误。ECC对内存稳定性要求高的服务器环境至关重要——单bit错误在普通内存上会导致系统崩溃——ECC可以自动纠正这种错误。
Chipkill(IBM)和RAS(Reliability/Availability/Serviceability)技术进一步保护——可以容忍整个内存芯片完全失效——在数据中心的内存模块上广泛使用。Chipkill将数据分布到多颗DRAM芯片上——一颗芯片完全故障时数据可以从其他芯片上恢复——比ECC提供更高的容错级别。部分现代CPU内存控制器内置了对Chipkill类能力的技术支持(如AMD的DDR5的ECC)——但不是全部PC硬件都支持。
复习检查(续)
DRAM读操作破坏性的含义——读出时电容放电——存储的值被破坏——读后必须立即执行写回(恢复)操作——所以"读"实际上包含一次隐藏的"写"。
tRFC(Refresh Cycle Time)对系统性能的影响——刷新期间(约350ns)整个DRAM芯片不能响应读写——频繁刷新期间可能造成1-2%的带宽损失。
DDR4-3200的实际核心时钟频率——DDR4-3200的数据传输率是3200MT/s——核心时钟频率为200MHz(因为预取单元宽度为8n——每次核心操作提供8个64位字的数据——然后I/O缓冲在外部时钟上下沿都发送——外部时钟频率=1600MHz倍频后等效频率=3200).
内存双通道与单通道的带宽差异——双通道可以将内存带宽翻倍——Intel i7-13700K双通道DDR5-5600带宽约90GB/s——同等配置降至单通道约45GB/s。
ECC内存对服务器的重要性——服务器长时间运行——单bit错误的发生概率随内存量和运行时间增加——ECC自动纠正——防止系统因单个bit错误导致不可恢复的崩溃和数据损坏。
内存控制器的集成历史
早期的计算机——内存控制器集成在主板北桥芯片中——CPU通过前端总线(FSB)与北桥通信——北桥再与内存通信。这种架构中——CPU访问内存的延迟较大——因为经过额外的芯片和总线。
AMD在2003年推出的Opteron和Athlon 64率先将内存控制器集成到CPU内部——消除了从CPU到北桥的FSB延迟——大幅降低内存访问延迟。Intel在2008年(Nehalem架构)也跟随此设计。现代CPU的内存控制器(IMC)直接与DDR4/DDR5内存条通信——通过每通道独立的总线控制多根DIMM。内存控制器的集成使系统总线和芯片组的复杂度降低——但CPU的物理封装引脚数增加了(需要直接连接到DIMM插槽的引脚)。
内存的等级——DIMM和RANK
一根DIMM内存条上包含多颗DRAM芯片(例如DDR5使用16颗2Gb芯片组成单条32GB)。DRAM芯片被组织成多个RANK——一个RANK是一组同时被选中读写的芯片——同一RANK内的所有芯片共享命令/地址总线——但各有自己的数据总线。多RANK配置允许在一条DIMM上组织更多的内存容量——但切换RANK需要额外的时钟周期延迟。
内存性能的影响因素汇总
| 因素 | 影响 | 说明 |
|---|---|---|
| 频率(MHz) | 高 = 高带宽 | DDR4 3200 vs 2133带宽高50% |
| CL延迟 | 低 = 低延迟 | CL14 vs CL18差异约2-4ns |
| 通道数 | 多 = 高总带宽 | 双通道vs单通道翻倍 |
| RANK数 | 多 = 可交错但增加延迟 | 单RANK vs 双RANK在延迟上相差约5-10ns |
| 刷新率 | 无直接影响 | 但温度高时刷新频率增加减少可用带宽 |
选择内存时需要根据应用的处理器需求(一般办公与内存密集型的AI训练和渲染对带宽要求差异极大)综合考虑这些因素。
复习检查(续二)
内存控制器集成在CPU内部为什么能降低延迟——消除了从前端总线(FSB)到北桥再到内存的额外传输延迟——CPU直接通过IMC访问内存——减少了约10-20ns的额外延迟。
DDR5的预取深度是多少——16n——比DDR4的8n增加了一倍——更高的预取深度允许内存核心工作在更低的频率——外部接口在更高数据率下运行。
内存RANK的概念——RANK是一组同时被选中的芯片的集合——一个RANK内的芯片共享命令/地址总线——切换RANK需要额外延迟。
为什么DRAM芯片的温度会影响刷新间隔——漏电随温度升高而加剧——高温下电容放电更快——刷新间隔必须缩短——否则数据会因漏电而丢失。
CL(CAS latency)对整体内存延迟的影响——CL=22相对于CL=14——在3200MHz下相差约5ns——对于敏感应用——低CL对首次访问的等待时间有明显改善。
内存访问模式对性能的影响
顺序访问——读取用户态代码的代码段时——指令在内存中连续排列——预取可以猜出并提前加载——几乎只受带宽限制——延迟基本被流水线隐藏。顺序大块读写(视频流、大型文件加载)的性能主要受限于内存带宽。
随机访问——大量随机小对象的加载——每个加载都对应不同的Cache Line——不能有效预取——需经历完整的tRCD+CL+tRP——延迟决定性能。随机访问模式下——更低的CL和更快的RAS/CAS延迟比更高的内存频率更有用。
混合模式——大多数真实负载(数据库、Web服务器)的行为介于两者之间——既有顺序扫描(如全表扫描)又有随机小I/O(如按索引查单行)。此时——适当平衡带宽和延迟——且CPU的Cache大小和命中率与内存参数一起——综合决定内存子系统的实际性能。
Rowhammer攻击与DRAM物理缺陷
Rowhammer是一种利用DRAM物理特性的攻击——通过反复、密集地访问一行(Row)内存——相邻行的电容中的电荷可能因电磁耦合效应而快速泄漏——导致相邻行的比特值翻转(0变1或1变0)。攻击者可以在没有软件漏洞的情况下改变相邻行中的比特——从而获得越权访问——修改页表项——提权到内核。
缓解措施:TRR(Target Row Refresh)——内存控制器检测到某行被大量激活时——自动刷新相邻的行——防止电荷泄漏积累到足以翻转的临界值。ECC内存也可以检测并纠正由Rowhammer引起的单bit翻转——但双bit无法恢复的翻转仍然可能导致程序或内核崩溃。
DRAM芯片随着制程缩小(从30nm到10nm级)——电容越来越小——存储的电荷量也越来越少——Rowhammer的阈值从原来的几十万次激活降低到几万次——使得攻击更难防御——这也是DDR5向后兼容TRR等缓解机制的原因之一。
复习检查(续三)
Rowhammer攻击的原理——频繁访问DRAM的某一行——导致相邻行的电容因电磁耦合泄漏电荷——造成相邻行的比特翻转——可以不经软件漏洞的内存权限检查修改系统数据。
TRR缓解Rowhammer的机制——内存控制器检测到某行被异常频繁地激活时——自动向相邻行发出刷新命令——恢复其电容的电荷量——防止电荷泄漏积累到翻转临界值。
顺序访问和随机访问在内存性能上的不同表现——顺序访问带宽决定性能——随机访问延迟决定性能——真实负载通常介于两者之间。
DDR5相比DDR4的改进——预取深度从8n增加到16n——更低的I/O电压——内置的错误校正码——更高的单条DIMM容量(可达128GB单条)。
内存频率与CL延迟的关系——高频内存通常CL更大(以绝对时间ns计可能变化不大)——DDR5-6000 CL48约16ns——DDR4-3600 CL18约10ns——高频率通常用更宽松的CL换取稳定性。
DRAM的生产工艺与良率
DRAM芯片的制造比逻辑芯片(CPU)更注重成本和单位容量——因为内存是标准品——价格战激烈。DRAM的单元尺寸在十几nm到几十nm之间(2024年最先进的是三星和SK海力士的1β工艺,约12nm级)。生产DRAM比生产逻辑芯片稍微简单因为不需要极致的线宽——但DRAM需要在更大的晶圆面积上实现更少的缺陷——以提高良率。DRAM制造商通过冗余行和列的修复技术——利用熔丝和备用单元替换有缺陷的行/列——使一颗芯片被多个冗余行覆盖——提高了整体良率。剩余的需要多个完备芯片封装到同一个DIMM模块——因此一个模块内个别DRAM芯片可能有微小的良率瑕疵——但被冗余修复隐藏。
内存的子系统和CPU互连
现代CPU(如Intel的Ring Bus和Mesh架构、AMD的Infinity Fabric)种包含集成的内存控制器——连接到L3缓存(LLC)。当L3缓存最后一次失命中——请求被发送到内存控制器——内存控制器将请求转换为DDR命令序列——通过DDR总线的读写数据完成从DRAM到L3的64字节数据传输——之后数据返回CPU。
系统各方面的性能终归受到内存子系统的性能上限显著影响——因本地等待可见的内存周期几乎是现代计算机所有主要应用(CPU运算、单机大模型推理、图形渲染载入)的通用瓶颈——成为系统设计中的重要决策对象。
复习检查(续四)
DRAM良率如何通过冗余提高——在芯片中设计额外的行和列——制造后测试发现缺陷——使用熔丝编程将缺陷地址映射到冗余行——提高芯片的合格率。
Intel的Ring Bus和Mesh架构在内存访问中的区别——Ring Bus将各个核心和内存控制器串联在一个环上——延迟低但核心数多了带宽不够——Mesh将核心和内存控制器组织成网格互联——核心数多时扩展性更好。
L3缓存未命中后的完整访存路径——核心→L3(未命中)→内存控制器→DDR总线→DRAM芯片tsd→行缓冲→列选择→数据传输返回→L3→核心——全过程约80-120ns。
内存训练与SPD配置
内存条上有一颗EEPROM芯片——存储SPD(Serial Presence Detect)数据——包含内存的时序参数(CL/tRCD/tRP/tRAS等)、容量、频率、电压和制造商信息。系统启动时——内存控制器读取SPD——按默认JEDEC标准时序参数初始化内存。如需更高性能——启用XMP(Intel Extreme Memory Profile)或EXPO(AMD)——内存控制器读取SPD中的超频配置——以更高的频率和略更宽松的时序运行——这需要CPU内存控制器和主板共同支持。内存训练是系统启动时——内存控制器通过多次读写测试找到内存工作的最佳电气参数(相位补偿、电压基准调整等)的过程——确保内存信号的稳定。训练失败(如超频过度)会导致系统无法启动——此时主板可能通过重启并恢复JEDEC默认参数来恢复。