一、存储系统层次
三级存储
- 主存储器(内存)
- 辅助存储器(外存)
- 高速缓冲存储器 Cache
- 存储元:存一个比特
- 存储单元:存一个存储字
二、SRAM 与 DRAM
| 类型 | 存储原理 | 特点 |
|---|---|---|
| SRAM(静态随机存取) | 双稳态触发器 | 读取速度较快,价格高 |
| DRAM(动态随机存取) | 利用存储单元栅电极电容存储的电荷量 | 集成度高,成本低;电容漏电需不断补电 |
刷新周期
DRAM 电容会漏电,需周期性补充电荷,每次补电的间隔时间称为刷新周期。
刷新方式
- 集中刷新:刷新过程中不允许 CPU 访问内存,这段时间称为死时间。
- 分散刷新:把存储系统工作周期划分成两部分,一部分交给读取和写入,另一部分负责刷新,会降低速率。
- 异步刷新:已知最大刷新周期为 2ms,设需刷新 n 行,则相邻两次刷新的间隔$t=\dfrac{2}{n}$;每隔时间 t 申请刷新一次,一次刷新一行,在最长刷新周期内完成全部刷新任务。
三、存储器级联思想
运算速度从快到慢依次为:寄存器 > 高速 Cache > 主存 > 外存 > 网盘。
把 CPU 计算将要用的内容放到寄存器,把寄存器可能用到的内容放到 Cache,剩下两个层次同理,逐级向下。
- CPU只与最靠近它的一级打交道:先查最近一级 Cache,未命中再由该级向下一级取,逐级向下。
- 每次取的是一整块,取回后填入发起这次访问的那一级缓存。
- 主存按地址取块;按内容(比较标记)查找的只有 Cache 自身。
- Cache 属于相联存储器,按内容访问:CPU 给出的主存地址被拆成
标记 + 组索引 + 块内偏移,组索引先定位组(地址方式),组内再并行比较标记判断命中(内容方式)。 - 相联存储器本身的定义仍是纯按内容寻址;主存、寄存器按地址寻址。二者并非"结合"在同一个器件里。
四、地址线与存储容量
地址线位数决定可寻址的最大范围。例如 36 位地址,可寻址范围为 $0 \sim 2^{36}-1$;若数据线宽度为 64 位,则一次可读 8 个字节(64 位数据),所以总存储容量为$ 2^{36}\times64 $位。
五、多体并行存储器
高位交叉编址
先得到体号,再译码得到体内地址,实际上仍是顺序存取。
低位交叉编址
先译码。由于程序在内存中连续存放,体内地址大概率相同,只需及时更正体内地址,即可迅速读取连续地址的内容(流水线读取)。
设模块字长等于数据总线宽度,模块存取周期为 T,总线传输周期为 r(每隔 r 就启动下一个模块),最多可并行 m 个模块:
m=\frac{T}{r}
相当于一次 T 内能够读取几个字。为尽可能高效,假设相邻字之间不存在时间空隙。
所以读取完连续的 m 个模块所需的时间为
$$T+(m-1)r=2T-r$$
六、主存容量扩展
位扩展法
假设数据总线宽度为 8,原本应从一片 DRAM 读取一整个字节;也可用位扩展法,把一个字节分到八片 DRAM 存储。读取一个字节时同时读取 8 片 DRAM,每片只给出一位,8 位拼凑出一个字节。
字扩展法
在单个 DRAM 地址位数基础上增加高位地址,经地址译码器译码产生片选信号,从而选择不同 DRAM。例如一片 DRAM 地址 14 位,再加 2 位最高位,即可并联 $2^2=4$ 片 DRAM,扩大寻址范围。
字位扩展法
将前两种方法结合:既把整个字节切分存储,又通过添加地址位数进行 DRAM 片选。
存储芯片地址分配与选中
- 线选法:有几片芯片就用几根线,选中哪一片哪根就为低电平(仅举例),浪费地址位数。
- 译码片选法:通过译码器译码,n 根地址线就能选中 2^n 个存储芯片。
七、外存
磁盘
- 组成:磁盘驱动器、磁盘控制器、盘片
- 磁盘地址:驱动器号 + 柱面号 + 盘面号 + 扇区号
记录密度
- 道密度:沿磁盘径向单位长度上磁道的数目
- 位密度:磁道单位长度能够记录的二进制位数
- 面密度:道密度与位密度的乘积
格式化与非格式化:格式化存储容量小于非格式化存储容量。非格式化容量上限即磁盘所有可利用的磁化单元总数;格式化按一定格式存储数据,会造成浪费,但便于管理。
平均读取时间:寻道时间 + 旋转延迟时间 + 传输时间
- 寻道时间:找到对应磁道的平均用时
- 旋转延迟时间:磁头找到目标扇区所用时间
- 传输时间:读取的数据运输到目的地所需时间
数据传输率:设数据传输率为 D,磁盘转速为 r 转/秒,磁道容量为 N,则
$$D=rN$$
磁盘阵列(RAID,独立冗余磁盘阵列)
| 级别 | 机制 | 特点 |
|---|---|---|
| RAID0 | 无冗余、无校验 | 连续数据存到不同磁盘,并行读取;增大容量、提高读取速度,但不设校验,出错无法纠正 |
| RAID1 | 镜像磁盘阵列 | 两份磁盘存一份内容,同时读取,一方故障无碍;但浪费空间 |
| RAID2 | 纠错海明码 | 采用能纠错的海明码 |
| RAID3 | 位交叉奇偶校验 | 位交叉奇偶校验磁盘阵列 |
| RAID4 | 块交叉奇偶校验 | 块交叉奇偶校验磁盘阵列 |
| RAID5 | 无独立校验盘 | 无独立校验盘的奇偶校验磁盘阵列 |
SSD 固态硬盘
组成:闪存芯片 + 闪存翻译层。闪存翻译层不仅把 CPU 对逻辑地址块的读写请求翻译成对物理硬件的访问指令,还可通过平均磨损延长 SSD 使用期限。
SSD 包含若干闪存芯片,每个芯片包含若干块,每块包含若干页。若对已含数据的某一页修改,必须先缓存这一块的内容到新的块才能修改;写入也类似,若想向某一页写入,必须先擦掉整个块,再一页一页写入这个块。
八、Cache
映射方式
| 映射方式 | 规则 | 特点 |
|---|---|---|
| 直接映射 | 主存每块只能对应一个 Cache 行(块号对 Cache 行数取模) | 被占用就替换原内容,效率较低 |
| 全相联映射 | 主存每块可映射到任意 Cache 行,行内记录相关信息 | 访存时需查所有 Cache 行 |
| 组相联映射 | Cache 分组,主存每块可映射到固定组的任意一行(前两者结合) | 组号由取模得到 |
替换算法
- RAND 随机替换:随机替换 Cache 行
- FIFO 先进先出:把最早进入 Cache 的行替换掉
- LRU 近期最少使用:把近期最少使用的 Cache 行替换掉
读操作
CPU 读取某数据,先到 Cache 找:
- 命中:把访问地址改成 Cache 地址;
- 未命中:从主存找出结果写入 Cache;若 Cache 满,按某种替换算法更新(一般用 LRU)。
Cache 一般设有 3 级。
写操作
CPU 写入某数据(以下默认 Cache 写命中):先修改 Cache 内容,再修改主存。
- 全写法:改了 Cache 就一起改主存
- 回写法:等该 Cache 块被替换出去时再更新主存。具体做法是设置标志位记录是否改动过,改过则在被替换时更新主存
写未命中
- 写分配法:把主存中的块写入 Cache,再在 Cache 中更新(与回写法配合)送回主存
- 非写分配法:直接修改主存内容,不用 Cache(与全写法匹配)
九、虚拟内存
将主存或外存的地址空间统一编址,形成虚地址空间,其中地址称为虚拟地址(逻辑地址),硬件中的地址称为实地址(物理地址)。
通过辅助硬件判定虚、实地址的映射关系:
- 若虚地址对应内容在主存 → CPU 直接访问主存;
- 否则先把辅存中的内容搬运到主存,CPU 再访问;主存满时也采用替换算法(同 Cache 部分)。
虚拟存储采用全相联映射和回写法,类 Cache 机制,缓存高频使用的内容。
为什么采用回写法?
虚拟存储系统对应的不是高速的 Cache 而是低速的外存,读写速度比较慢,应尽量减少读写操作,所以采用回写法。
页式虚拟存储
页表(放在主存中)用一个逻辑表格维护信息:
- 有效位(装入位):是否在主存中
- 脏位(修改位):标识是否修改
- 引用位(使用位):表示是否使用过,以便进行替换
CPU 访问流程:
- 有效位为 1:页表内存放的是主存的物理页号;虚拟地址 = 虚拟页号 + 页内地址,这个页内地址就是真实的主存页内地址,把物理页号与页内地址拼接即为物理地址。
- 有效位为 0:先检查请求是否合理;合理则看有没有空页框(主存块),有就用空页框,没有就用替换算法选一个牺牲页;若牺牲页脏位为 1,还要更新外存内容。
快表 TLB
TLB 存储经常使用的虚页表项,TLB 标记用于表示这一条表项取自哪个虚页号对应的页表项。思想类似 Cache,把高频使用的内容暂存并实时更新。
段式虚拟存储
段式存储以段为单位存储。段表存储的信息包含段首址、装入位、段长:这里装入位含义同页式;段表只记录段首地址和段长度,便于管理修改,但一个段不一定紧挨着下一个段,会产生外部碎片造成浪费。
十、存取时间与存储周期
- 存取时间:完成一次存/取所需的时间,分为读出时间和写入时间;计时起点都是存储器收到有效地址的时刻,结束时间分别是数据稳定输出的时刻和数据被完全写入的时刻。
- 存储周期:进行两次独立存取操作的最小时间间隔,= 存取时间 + 恢复时间(恢复时间是两次访问之间器件复原所需时间,与数据总线传输无关)。
- 例:DRAM 靠电容电量表示信息,必须不停扫描刷新,一次存取操作之后可能要刷新,存在恢复时间;恢复时间越长,连续访问效率越低。