第三章 存储系统

3.1 存储器概述

按照离CPU的层次分类:

  • Pasted image 20250304111239.png
  1. 寄存器
  2. Cache
  3. 主存
  4. 辅存、外存:磁盘、U盘、磁带、光盘
    其中:
  5. Cache-主存之间的数据同步是依靠硬件自动完成的(解决了CPU和主存速度不匹配的问题)
  6. 主存-辅存之间的数据置换的方式有:
    1. 操作系统的页面置换算法(实现了虚拟存储系统)
    2. 普通文件操作等

按照存储介质进行分类:

  1. 半导体存储器
  2. 磁性存储器
  3. 光存储器

按照存取方式进行分类:

  1. 随机存取存储器(RAM、Random Access Memory):读写任意一个存储单元所需时间都相同,例如内存等。
  2. 顺序存取存储器(SAM、Sequential Access Memory):读写一个存储单元所需时间取决于存储单元所在位置,例如磁带等。
  3. 直接存取存储器(DAM、Direct Access Memory):既有随机存取的特性,也有顺序存取的特性。区域(扇区)间随机读取,区域(扇区)内顺序读取,例如磁盘等。
  4. 相联存储器(CAM、Content Addressed Memory):可以按照内容检索到存储位置进行读写的存储器,例如快表。

按照可更改性分类:

  1. 读写存储器
  2. 只读存储器

按照信息的可保存性分类:

  • 按照断电后信息是否可保存分类:
    1. 易失性存储器:断电后信息丢失
    2. 非易失性存储器:断电后信息不丢失
  • 按照信息读出后,原存储信息是否丢失分类:
    1. 破坏性读出存储器:读取后原信息被破坏,例如DRAM
    2. 非破坏性读出存储器:例如SRAM、磁盘、光盘等

3.2 主存储器

3.2.1 主存储器的基本构成

主存储器的基本构成如下图所示:
Pasted image 20250306142951.png
Pasted image 20250305160157.png
其可以简化为下图的结构:
Pasted image 20250305160216.png
其中:

  • MAR为内存地址寄存器(MAR、MDR都曾集成在RAM芯片中,但现代计算机中是集成在CPU中)
  • MDR为内存数据寄存器
  • 存储器负责存储二进制数据

3.2.2 DRAM和SRAM芯片

3.2.2.1 DRAM芯片

DRAM为动态随机存储器,通常使用栅极电容存储信息,其特性有:

  • 功耗较SRAM低
  • 一个基本存储单元只需要一个晶体管,密度比SRAM高,速度比SRAM慢
  • 读出数据时会消耗电容中的电荷,读出后应有重写操作,也称"再生"
    • 因此写入速度通常比读取慢(例如Cache)
  • 需要定期刷新以保持数据(电荷会流失),通常2ms就要刷新一次
  • 通常用于制作主存(运行内存)

DRAM和SRAM的存储单元差异可见下图:
Pasted image 20250306161121.png

  • 注:左为DRAM,右为SRAM

此外,由于DRAM内存较大,因此其译码器在设计时也不能像左侧那样只使用一个译码器去寻找 个地址(此方案需要在译码器和存储单元之间连接 个选通线),所以通常设计成右侧的二维排列形式,将地址拆分为行地址和列地址(当然,现在已经有了三维的排列形式)。
Pasted image 20250306162457.png

DRAM地址线复用技术:同一根线先后传输行地址和列地址,以达到行列地址线的复用。

3.2.2.1.1 DRAM的刷新

DRAM的刷新:

  1. 通常以行为单位,每次刷新一行。
  2. 刷新时先读出数据,随后再次写入。
  3. 刷新会占用一个读写周期。
    因此在刷新时,有如下的刷新策略:
  4. [分散刷新]:每次读写完都刷新一行:
    • 会导致读写的存取周期翻倍
  5. [集中刷新]:2ms内集中刷新一次:
    • 这种策略在刷新时,CPU无法访问RAM,称为访存"死区"
  6. [异步刷新]:依旧保持2ms刷新一次,但是一次只刷新一行,并把刷新操作分散到周期内:
    • 这种策略依旧会有死区,且死区总时长与上一方案相同,但是更容易把刷新操作分散到CPU不需要访问内存的时间内(例如CPU译码阶段)。

3.2.2.2 SRAM芯片

SRAM为静态随机存储器,通常使用双稳态触发器存储信息,其特性有:

  • 功耗比DRAM高
  • 一个基本存储单元需要六个晶体管,密度地,价格高,速度更快
  • 其有外置供电,读出数据不会破坏电平状态
  • 通常用于制作Cache

DRAM和SRAM对比如下:

类型特点
SRAM DRAM
信息存储单元 双稳态触发器 电容
读出是否破坏数据
读出后是否需要重写
访问速度
集成度
功耗
制造成本
断电后数据是否丢失
是否需要刷新
常用场景 Cache 运行内存

3.2.2.3 RAM的访问周期

Pasted image 20250305160157.png
以上图为例,一般来说,RAM的访问有如下几个环节:

  1. CPU(直接或通过内存总线)把欲访问的地址放入内存地址寄存器(MAR)
  2. 使用读写控制信号触发内存访问操作
  3. RAM在时序控制逻辑的控制下:
    1. 使用地址译码器寻找记忆单元中MAR中地址对应的数据(行激活、列选择等)
    2. 将MAR中地址对应的数据存入内存数据寄存器(MDR)
  4. 随后数据(直接或通过内存总线)传回CPU(的Cache中)
    上述过程中,RAM的速度远慢于CPU的速度,且具体流程和时间消耗可见章节DRAM的时序
    而为了解决RAM速度远低于CPU速度的问题,可见后续章节RAM的并行访问与内存一致性技术。
3.2.2.3.1 [了解]DRAM的时序

CPU访问DRAM的流程为:

  1. 确定内存通道,以及单个内存条上的DIMM。
  2. Bank及行列选择:选择内存颗粒中的某个Bank,并指定目标的行列地址。
  3. 行激活:
    1. 内存控制器向Bank发送RAS(Row Address Strobe)信号,传入行地址。
    2. 将Bank中的整行数据复制到行缓冲器(因为DRAM读取数据会破坏电荷)。
    3. 行激活完成后,颗粒会自动将行缓冲器中的数据回写到原存储单元。
  4. 列选通:
    1. 内存控制器向Bank发送CAS(Column Address Strobe)信号,传入列地址。
    2. 从行缓冲器中选定特定的列数据。
  5. 数据传递:
    1. 数据通过内存总线回传CPU。
  6. 预充电:
    1. 完成当前行操作后,内存控制器发送Precharge命令,关闭当前激活的行。
    2. 行缓冲器清空,Bank准备接受下一行激活请求。

则DRAM的时序参数(并非总耗时)主要有:

  1. 行激活时间(tRAS):行激活后必须保持开启的最短时间(要等待其他操作完成),,若
  2. 行到列延迟(tRCD):行激活后,发送CAS信号前,必须等待的最小时间间隔(用于等待行缓冲器稳定)
  3. 列地址选通延迟(CL):CAS信号发送后,数据通过内存总线开始回传的时间间隔。
  4. 行预充电时间(tRP):关闭当前已打开的行后(即预充电完成后),在激活新行之前,必须等待的时间。

则DRAM访问的时间线为:

        tRCD          CL            tRP
    |-----------|-------------|------------|
    ↑           ↑             ↑            ↑  
发送RAS      发送CAS       数据返回     下次行激活  
(行激活)     (列选通)      (数据传递)     (新访问)

则DRAM访问的耗时为:

  1. 普通连续读取或单次读取:
    Pasted image 20250310141542.png
  2. 含有快速页面模式(Fast Page Mode,FPM)的同一行中的多次连续读取:
    Pasted image 20250310141458.png
    • 使用于486和早期Pentium时代,目前已经完全淘汰
  3. EDO(Extended Data Out、1994年后):
  4. 同步DRAM(SDRAM、1996年后):
  5. RDDRAM(Rambus DRAM、1999年):
  6. 双倍速率同步RAM(DDR SDRAM、2000年后):

3.2.3 只读存储器

只读存储器、Read Only Memory,ROM。其通常有如下几种:

  1. MROM:掩膜式只读存储器,厂家生产后所有人都无法重写。
  2. PROM:可编程只读存储器,用户可以用专用的PROM写入器写入信息,写一次后数据就不可更改。
  3. EPROM:可擦除可编程只读存储器,允许用户写入信息和用某种方式擦除,可多次重写
    1. UVEPROM:使用紫外线擦除,擦除时只能全部擦除。
    2. EEPROM:用电擦除,擦除时可选字或区域进行擦除。也可以缩写为E2PROM。
  4. Flash:在EEPROM基础上发展而来,可进行多次快速擦除重写。写入前要擦除,写入速度比读取慢。每个存储元只需要一个MOS管+一个浮栅。

3.2.4 RAM的并行访问与内存一致性

3.2.4.1 双端口RAM

上述章节所描述的RAM模型只有一个数据总线和一个地址总线,当有多个硬件(如多核CPU、DMA等)需要同时访问时,则会遇到严重的性能问题。

那么此时可以引入双端口RAM,双端口RAM有两个地址总线和两个数据总线,支持两个设备的并行访问:
Pasted image 20250307164714.png
其访问规则为:

行为
规则
两个设备同时读取不同的地址 允许
两个设备同时读取相同的地址 允许
两个设备同时写入不同的地址 允许
两个设备同时写入相同的地址 不允许,RAM向设备发送Busy信号
两个设备分别读写相同的地址 不允许,RAM向设备发送Busy信号

3.2.4.2 多体并行存储器(交叉编址)

在章节DRAM的时序中讲到,在CPU完成一次对RAM的某个Bank访问之后,需要一定时间(tRP)的恢复才能访问该Bank的新行。但是在该等待时间内可以访问其他的Bank,因此需要将多个Bank之间进行交叉编制,明显地,交叉编址主要有如下两种:

  1. 高位交叉编址:
    • Pasted image 20250307171658.png
  2. 地位交叉编址:
    - Pasted image 20250307171710.png
    类似于横向编址和纵向编址。由于局部性原则,内存访问通常具有局部性。为了最大化RAM利用率,减少平均存取周期,一般都选用低位交叉编址:
  • 通常多体并行存取的体数量要大于"存取周期/存取时间"的值。
  • Pasted image 20250310145259.png

3.2.4.3 单体多字存储器

将多个存储单元按高低位横向拼接,例如将4个1Byte存储体拼成4Byte存储体:
Pasted image 20250310150039.png

  • 可以用于将若干个窄字宽的存储器拼接到CPU的内存总线的位宽,可见章节主存容量的拓展

3.3 主存储器与CPU之间的连接

3.3.1 连接原理

现代计算机中:

  • MAR、MDR集成于CPU中,CPU和内存颗粒通过数据总线、地址总线、控制线进行连接:
    • 示意图为:Obsidian_r0hUfblY63.png
    • 片选线: (高电平有效)或 (低电平有效)或 /
    • 读写控制:
      • 读写合并控制: / / /
      • 读写独立控制:
        • 读控制: /
        • 写控制: /
  • 单颗DRAM芯片的地址总线通常为14-18位,数据总线宽度常见为:
    • 4位:用于高密度存储应用,例如服务器内存
    • 8位:用于消费级应用,例如PC
    • 16位:常用于低功耗移动端设备
  • CPU和主存储器的连接通常为:
    Pasted image 20250305160157.png
    • 其中:
      • 数据总线被命名为:,例如 ...
      • 地址总线被命名为:

3.3.2 主存容量的拓展

3.3.2.1 位拓展法

当DRAM存储芯片的数据位宽度小于CPU的数据总线宽度时,可以将若干个DRAM存储芯片在位宽度上拓展到对应的总线宽度即可:
Pasted image 20250310154223.png

  • CS信号也同步控制即可。

3.3.2.2 字拓展法

当DRAM存储芯片的地址位宽度小于CPU的地址总线宽度,并且需要拓展到足够的内存时,可以将地址总线用译码器进行管理即可:
Pasted image 20250310155642.png

3.3.2.3 字位同时拓展法

排列组合即可:
Pasted image 20250310160127.png

3.4 外部存储器

本章节主要讲解外部存储器的硬件特性,至于操作系统及软件层面的应参见操作系统学科。

3.4.1 磁表面存储器

磁表面存储器主要有如下几种:

  1. 磁带存储器
  2. 磁盘存储器
  3. 磁鼓存储器
    磁表面存储器主要依靠对存储器表面的磁层按照充磁方向进行信息存储:
    Pasted image 20250311144507.png
    因此磁表面存储器每次只能读写1Bit数据,而计算机中的最小数据单元为1Byte,因此硬盘控制器中需要增加串并转换电路、数据编码器、数据译码器等部分,可见下图:
    Pasted image 20250311145148.png
    磁盘存储区域的划分可参见下图(详可见操作系统):
    Pasted image 20250311145636.png
    值得注意的是磁盘通常是上下双面
    Pasted image 20250311145503.png

补充一些操作系统中未提及的概念:

  • 记录密度:指盘片上单位面积记录的二进制的信息量,通常以道密度、位密度和面密度表示。
    • 道密度:沿磁盘半径方向单位长度上的磁道数
    • 位密度:磁道单位长度上能记录的二进制代码位数(因此内圈的位密度大于外圈位密度)
    • 面密度:位密度和道密度的乘积

3.4.2 SSD

SSD的构成可参考下图:
Pasted image 20250313100638.png
内存翻译层由主控制器负责,SSD上通常由多个闪存芯片(EEPROM),通常块大小为16KB~512KB,页大小为512B~4KB。其寻址速度比HDD更快。

3.4.3 RAID阵列

RAID阵列全名为Redundent Array Inexpensive Disks,即廉价冗余磁盘阵列。该技术可以将多个独立物理磁盘组成一个独立的逻辑盘,并将数据分散在多个物理盘上交叉存储、并行访问、冗余校验。(注意RAID并不是备份技术)

通常来说,RAID有如下几种阵列方式,以若干连续数据 A1 A2 A3 ... A8 为例:

  • RAID0:无冗余无校验的磁盘阵列
    • Pasted image 20250311160623.png
    • 特性:
      • 总存储容量不变
      • 并发读取速度
      • 无冗余,单块发生错误数据即永久丢失
      • 无校验,无法发现数据错误
  • RAID1:磁盘镜像阵列
    • Pasted image 20250311160941.png
    • 特性:
      • 总存储空间 是所有RAID中最低的
      • 并发读取速度
      • 有冗余,只要还有一块磁盘存活,则数据仍然无丢失
      • 有校验,可以发现错误,安全性是所有RAID中最高的
      • 支持热替换
  • RAID2:采用纠错的海明码的磁盘阵列
    • Pasted image 20250311161451.png
    • 特性:
      • RAID2中有两种硬盘,分别为数据盘和校验盘。
      • 校验盘数量 和数据盘数量 的关系要满足: (海明码要求)。
      • 最小磁盘数量:
        • 数据盘至少一块,校验盘至少两块,但是此时并无意义。
        • 通常来说最少的磁盘数量为7块,4块数据,3块校验(即如图所示的组合)。4+3组合拥有纠正一位错,发现两位错的能力,即在校验盘正常时,允许损坏一个数据盘。
      • 以位为单位进行分割存储。
      • 海明码计算开销较大。
      • 是早期技术,目前已被淘汰。
  • RAID3:位交叉奇偶校验的磁盘阵列
    • Pasted image 20250313094236.png
    • 特性:
      • 使用更加简单的奇偶校验算法进行数据校验。
      • 当有一个硬盘损坏时,数据不会丢失。
      • 以条带为单位进行分割存储,提高了读取并行度,但是写入效率差。
      • 无论数据写入量是多少,校验盘每次都需要同步校验码,写入压力大,更容易损坏。
      • 奇偶校验只能查错不能纠错。
  • RAID4:块交叉奇偶校验的磁盘阵列
    • Pasted image 20250311162117.png
    • 特性:
      • 使用了更大的条带深度,读取性能好,但写入效率差,每次写入都必须操作校验盘。
      • 校验盘容易损坏。
  • RAID5:无独立校验的奇偶校验的磁盘阵列
    - Pasted image 20250313095944.png
    - 特性:
    - RAID5将校验码分散存放到各个硬盘中。
    - 此时没有数据盘和校验盘的概念,硬盘之间为平等的关系,磨损均匀,且硬盘重要性相同。
    - 通常其默认容量为 倍单盘容量,每 位数据就增加一个校验位。
    - 最多允许一块硬盘损坏。
    - 读写性能高,理论上最高读写性能只略低于 倍的单个磁盘速度。
    而上述阵列方式之间可以二次组合,例如:
  • RAID10:
  • RAID01

因此单位数据成本上:RAID0 > RAID1 > RAID2 > RAID3 > RAID4 > RAID5

3.5 Cache

3.5.1 程序访问的局部性原理

略,详见操作系统。

3.5.2 Cache的基本工作原理

Cache集成于CPU内部,用于缓和CPU和RAM之间的速度差距。
SMP处理器的基本内存缓存架构如下图所示:
Pasted image 20250221133107.png
其多个CPU之间的L1、L2 Cache每个CPU独立使用,L3和RAM是共享使用。

而在CPU进行运算或操作时,其数据一定存放于寄存器中。因此在具有多级缓存的CPU架构下,CPU操作数据时,其流程为(假设访问区域合法):

  1. 查询L1缓存中有无目标数据,如有则读入寄存器,如无则查询L2缓存
  2. 查询L2缓存中有无目标数据,如有则读入L1缓存,如无则查询L3缓存
  3. 查询L3缓存中有无目标数据,如有则读入L2缓存,如无则查询RAM
  4. 查询目标地址是否在RAM中,如有则读入缓存,如无则去Swap中查找

需要注意的是:

  1. 位于L3或L2的数据也需要逐级流动到L1才能到寄存器不可直达。不过此过程由硬件自动完成。
  2. 上述的数据命中与拷贝的单位是缓存行MESI协议管理的基本数据单元也是缓存行
  3. 上述过程中的L1、L2更新会按照策略自动进行。
  4. DMA的使用场景为:外设到内存、内存到外设、内存到内存、外设到外设。
    1. 上述寄存器指的是CPU的控制/状态寄存器,而非外设的数据缓冲区寄存器。因此DMA无法完成CPU的控制/状态寄存器到内存的操作。

在性能分析时,可以使用各级的命中率计算访存时间。

3.5.3 MESI缓存一致性协议

如上述所述,CPU在缓存-内存分级管理时,其基本单位是缓存行(也可叫做缓存块、Cache块等),而MESI就是硬件维护缓存一致性的基础协议。其将缓存行的状态分为如下四种:

  1. Modified:已修改;缓存行已被修改,和主存中数据不一致。
  2. Exclusive:独占;缓存行未被持有,但与内存一致。
  3. Shared:共享;缓存行被多个核心共享,且各副本一致。
  4. Invalid:无效;缓存行无效,必须从其他核心或主存中重新加载。

在L1、L2缓存中,每一个缓存行都存储的有一份MESI状态标志。当一个核心修改缓存行时协议通过广播消息使其他核心的对应缓存失效(Invalidation),从而确保对共享数据的操作是原子性的
在早期Intel Core系列的L3中也使用MESI进行管理,但是现在的x86和ARM中已经改为MOESI协议。

3.5.4 Cache和主存的映射方式

在解决了缓存一致性问题之后,还需要解决Cache和RAM映射关系的问题。Cache和主存的映射方式主要有如下三种:

  1. 全相联映射:Cache中的数据和主存中的数据可以任意映射
  2. 直接映射:一个主存块中的数据只能存放到规定的缓存行中,类似于Hash Table
  3. 组相联映射:将若干缓存行分组,一个主存块中的数据可以存放到对应Cache组中的任意一个缓存行中。例如下图组相联映射中,主存块0、4、8、12可以放到Cache组0中的任意一个缓存行中。
    Pasted image 20250313113706.png
    而要记录上述的映射关系,可以在缓存行前面记录其所来自的主存块号即可。该主存块块号和MESI标志通常一起存放。

需要注意的是,Cache和主存之间需要实现双向匹配,一方面需要允许主存能够快速的向Cache中缓存数据,另外一方面也要能快速的使用物理内存地址寻找到对应的缓存行。那么上述三种映射方式的匹配规则分别为:

  1. 全相联映射:
    • RAM->Cache:记录缓存行对应的完整的主存块号。
    • Addr->Cache:并行比较所有缓存行的内存块号。
    • 优点:自由度最高,Cache容易得到充分利用
    • 缺点:需要记录最长的内存块号,需要内置相当多的并行匹配电路,硬件成本较高。
  2. 直接映射:
    • RAM->Cache:每个内存块只能对应唯一一个缓存行,但是一个缓存行可以对应多个内存块,因此其依旧需要一个长度较短的空间记录其所来自的内存块号。
    • Addr->Cache:只用校验对应地址的缓存行即可。
    • 优点:硬件结构最为简单,也只需要记录最短的内存块号。
    • 缺点:灵活性最低,同一Cache地址的内存块无法同时使用Cache缓存。
  3. 组相联映射:
    • RAM->Cache:需要记录相对较长的主存块号
    • Addr->Cache:并行比较组内的缓存行对应的内存块号。
    • 总体设计较为折中,现代CPU通常使用该策略。

3.5.5 Cache替换算法