13存储系统
3.1 存储系统基本概念
存储器功能:存放二进制信息
3.1.1 存储器层次化结构
从上自下分别为:CPU寄存器 - 高速传冲存储器 - 内存 - 辅存 - 外存
- 越上层越接近CPU\速度越快、容量越小、价格越高。外存的速度最慢、容量最大、价格最低
- 高速缓冲存储器一般指Cache,内存一般指主存,辅存一般指磁盘,外存一般指磁带、光盘
有些教材讲安装在电脑内部的磁盘称为辅存,把U盘、光盘等称为外存;也有些教材将磁盘、U盘、光盘统称为辅存或外存
- 在辅存中的数据只有调入到主存后才能被CPU访问
- Cache-主存数据交换,解决了主存和CPU速度不匹配的问题。这部分数据交换由硬件自动完成,对软件开发人员透明
- 主存-辅存数据交换,实现了虚拟存储系统,解决了主存容量不够的问题。这部分数据交换由硬件和操作系统一同完成,硬件、软件工程师均需要设计程序
3.1.2 存储器的分类
按存储器层次分类:
- 高速缓存:Cache
- 主存储器:主存、内存
- 辅助存储器:辅存、外存
高速缓存、主存储器可以直接被CPU读写
按存储介质分类:
- 半导体存储器:以半导体器件存储信息,如Cache、主存
- 磁表面存储器:以磁性材料存储信息,如磁盘、磁带、软盘
- 光存储器:以光介质存储信息,如光盘
按存取方式分类:
- 随机存取存储器,Random Access Memory,RAM:读写任何一个存储单元所需时间都相同,与存储单元所在的物理位置无关。如主存、固态硬盘
- 顺序存取存储器,Sequential Access Memory,SAM:读
写一个存储单元所需时间取决于存储单元所在的物理位置。如磁带 - 直接存取存储器,Direct Access Memory,DAM:既有随机存取特性,也有顺序存取特性。先直接选取信息所在区域,然后按顺序方式存取。如机械硬盘
串行访问存储器:读写某个存储单元所需时间与存储单元的物理位置。顺序存取存储器SAM、直接存取存储器DAM均是串行访问存储器
- 相联存储器,Associative Memory:也叫可以按内容访问的存储器,Content Addressed Memory,CAM,可以按照内容检索到存储位置进行读写。"快表"就是一种相联存储
- 相联存储器基本原理:把存储单元所存内容的某一部分作为检索项,即关键字项,去检索存储器
- 在计算机系统中,相联存储器主要用于虚拟存储器存放段表、页表和快表,以及高速缓冲存储器Cache中存放块地址。以上两种应用中都需要快速查找
按信息的可更改性分类:
- 读写存储器,Read/Write Memory:既可读、也可写的存储器。如:磁盘、内存、Cache
- 只读存储器,Read Only Memory:只能读,不能写的存储器。如:实体音乐专辑通常采用CD-ROM,实体电影采用蓝光光碟,BIOS通常写在ROM中
事实上很多ROM也可多次读写,只是比较麻烦
按信息的可保存性分类:
- 易失性存储:断电后,存储信息消失的存储。如主存、Cache
- 非易失性存储:断电后,存储信息依然保持的存储。如磁盘、光盘
关于信息保存性引申出两个概念
- 破坏性读出:信息读出后,原存储信息被破坏。如DRAM芯片,读出数据后要进行重写
- 非破坏性读存储器:信息读出后,原存储信息不被破坏。如SRAM芯片、磁盘、光盘
3.1.3 存储器性能指标
存储容量:总容量 = 存储字数/存储单元个数 × 存储字长。如1M×8位
MDR的位数反应了存储字长
单位成本:每位价格 = 总成本/总容量
存储速度:数据传输率=数据的宽度/存储周期
数据的宽度即存储字长
- 一次完整的存取周期\(T_m\)包括存取时间\(T_a\)以及恢复时间\(T_b\)
- 存取时间\(T_a\):存取时间是指从启动一次存储器操作到完成该操作所经历
的时间,分为读出时间和写入时 - 存取周期\(T_m\):存取周期又称为读写周期或访问周期。它是指存储器进行
一次完整的读写操作所需的全部时间,即连续两次独立地访问存储器操作(读
或写操作)之间所需的最小时间间隔 - 对于单次读写只需要存取时间\(T_a\),但连续读写就需要将恢复时间包含进去,实际单次读取的时间需要\(T_m\)
- 存取时间\(T_a\):存取时间是指从启动一次存储器操作到完成该操作所经历
- 主存带宽\(B_m\):主存带宽又称为数据传输率,表示每秒从主存进出信息的最大数量,单位为字/秒、字节/秒(B/s)或位/秒(bit/s)
3.2 主存储器
存储器由存储体、地址寄存器MAR、数据寄存器MDR组成,由时序控制逻辑控制
3.2.1 存储体
存储体包含多个存储元,由一个MOS管以及电容两个元件组成
- MOS管相当于一个电控开关,输入电压达到某个阈值时MOS管可以接通
- 电容是一个存储电荷的元件,有两块金属板,当金属板两端有电压差时,可以存储电荷。在存储元中,电容其中一款金属板接地,即电势为0,当另外一侧存在高电压时即可让电容存储电荷
- 当电容两侧是否存在电势差/电压的状态表示二进制0/1
- 读取二进制信息:接通MOS管后,如果检测到存储元有高电平说明该位置表示从该存储器中读出二进制1,反之读出0
- 写入二进制信息:接通MOS管后,向存储元输入高电平信号,让电容进行充电,随后再断开MOS管完成二进制1的存储
一个存储元表示一个二进制位,多个存储元构成了一个存储单元,多个存储单元构成了一个存储体
存储单元大小就是存储字长,即字长
3.2.2 译码器
利用地址来读取相应位置的存储单元信息,需要通过译码器实现
- 对于n位MAR地址,对应\(2^n\)个存储单元
- 对于来自地址总线传入的一个MAR地址,对应着唯一的字选线/选通线,也对应着唯一的存储单元。当MAR输入到译码器中时,会将高电平输入到对应的字选线,将所在的存储单元所有存储元MOS管接通
- 每个存储单元与存储字长相同数量的数据线/位线相连,用于读出存储单元中每一位的二进制信息,并传输到MDR中。MDR与数据总线相连,数据总线的宽度=存储字长
地址总线、数据总线均与CPU相连
实际在存储芯片中,除了译码器元件,还有驱动元件,用于放大电信号保持MDR、MAR的电信号稳定
3.2.3 控制电路
控制电路作为存储体芯片的核心控制元件,用于控制与实现数据总线、地址总线、存储体之间数据通信
- 地址总线将数据传入电信号给MAR,由于电信号传入可能不稳定,只要当电信号稳定后,控制电路才会将MAR的地址信息传输给译码器
- 同理,译码器给相应的字选线输入高电平读出MDR后,也需要等待存储元输出的电信号稳定后,控制电路才能将MDR数据传输给数据总线
- 控制电路有三个控制信号输入,分别为片选线、读/写控制线
- 片选线,用\(\overline{\text{CS}}\)或\(\overline{\text{CE}}\)表示,用于标明当前是否使用该存储体元件
该符号上划线表示该信号低电平有效
- CS,Chip Select,表示芯片选择信号;CE,Chip,表示芯片使能信号
- 一个内存条可能存在多块存储芯片,计算机需要通过对某个芯片输入低电平,其他芯片输入高电平的方式来选择对特定芯片进行读写操作
- 读写控制线,分别用\(\overline{\text{WE}}\)、\(\overline{\text{OE}}\)表示
- 使用两根读/写线时,WE低电平信号表示存储器正在执行写操作,OE低电平信心好表示存储器正在执行读操作
- 使用一根读/写线时,WE低电平信号表示存储器正在执行写操作,高电平信号表示正在执行读操作
- 使用不同根数的读写控制线,会影响存储体芯片对外暴露的金属引脚数量
- 片选线,用\(\overline{\text{CS}}\)或\(\overline{\text{CE}}\)表示,用于标明当前是否使用该存储体元件
3.2.4 存储芯片的基本组成
综上所述,一块存储器芯片包括译码、驱动元件,存储元/体构成的存储矩阵,读写控制电路,以及对外暴露的地址线、数据线、片选线、读/写控制线
- 每个存储芯片对外的线都会对应一个金属引脚。假设某存储芯片存储字长为n bit,使用两根读写控制线,则存储芯片至少2n+3个引脚
每个存储芯片除了上述引脚外,还需要一个供电引脚和接地引脚,因此至少2n+5个引脚
- 对于 a x b 位的存储芯片,a反映了存储单元的总数,b反映了每个存储单元中包含的存储体数
- 如8k x 8位的存储芯片,则表示容量为\(2^{13}\) x 8bit;64k x 16位的存储芯片,表示容量位\(2^{16}\) x 16bit
3.2.5 主存寻址
现代计算机通常按字节编址,即一个字节对应一个地址。假定机器字长为4B,对于总容量为1KB的存储,则有\(2^{10}\)个地址,因此共需要10根地址线
- 按字节寻址:共1K个寻址单元,每个单元占1B
- 按字寻址:共256个寻址单元,每个单元占4B
- 按半字寻址:共512个寻址单元,每个单元占2B
- 按双字寻址:共128个寻址单元,每个单元占8B
3.3 SRAM和DRAM对比
对比总结
| 对比项目 | SRAM | DRAM |
|---|---|---|
| 存储信息 | 触发器 | 电容 |
| 破坏性读出 | 读出不会破坏信息 | 读出会破坏信息 |
| 是否需要刷新 | 不需要 | 需要 |
| 送行列地址 | 同时送 | 分两次送 |
| 运行速度 | 快 | 由于需要刷新,运算速度慢 |
| 集成度 | 低 | 高 |
| 发热量/功耗 | 低 | 高 |
| 存储成本 | 高 | 低 |
| 主要用途 | 高速缓存 | 主机内存 |
3.3.1 DRAM
动态RAM,Dynamic Random Access Memory
- DRAM主要用于主存,使用栅极电容存储信息,断电后信息消失
- 使用栅极电容存储信息,在读出二进制信息需要电容进行放电,电荷被放出后信息被破坏属于破坏性读出,读出后应有重写操作,也称"再生"。因而读写速度更慢
- 同时由于二进制信息通过电容进行存储,电容中的电荷只能维持2ms,即使不断电,2ms后信息也会消失。因此2ms内必须进行刷新,即给电容充电一次
- 每个存储元制造成本更低,集成度高,功耗低
DRAM的容量由位平面数、存储阵列的行数和列数决定

- DRAM芯片的容量 = 位平面数 x 行数 x 列数
- 其中
- 位平面表示,提供1位数据的行与列的交面
- 图中芯片规格为4096 x 4096,4096 cols x 4 构成该SRAM的行缓冲区大小,同理4096 rows x 4 构成SRAM的列缓冲区大小
DRAM的刷新
刷新时间:
- 由于电容内电荷一般只能维持2ms,因此需要在2ms内进行一次刷新
刷新数量:
- 每次需要刷新一行存储单元,且同时对所有DRAM芯片的某一行进行刷新
- 对于n位的MAR,需要\(2^n\)根字选线/选通线用于确定读写哪个存储单元,如果将\(2^n\)根线接在译码器上,电路实现上比较困难
- 将选通线一维排列调整为二维排列,并拆分成行、列排列,即\(2^{n/2}\) x \(2^{n/2}\)的矩阵,因此每个存储单元被标记为(\(x_i\),\(y_i\))的编号
要求DRAM行、列地址等长
- n位的MAR被拆分成\(A_{n-1}\) ~ \(A_{n/2}\)以及\(A_{n/2-1}\) ~ \(A_0\)两部分,分别指向行地址译码器、列地址译码器,因此行/列地址译码器只需要接\(2^{n/2}\)根线,大大降低了电路制作难度
随着制作工艺的上升,现代制作工艺已经实现了三维的排列
刷新过程:
- 刷新有专门的硬件支持,读出一行信息后重新写入,刷新过程也占用1个读/写周期\(T_m\)
- DRAM芯片内部又一个行地址生成器,也叫书信计数器,由他自动生成行地址
- 刷新时针对一行中所有存储单元进行的,无需进行列寻址
- 刷新由存储器独立完成,不需要CPU控制
- 但是刷新过程中,CPU是无法进行访存的,即存在访存死区
刷新策略:
- 假设DRAM内部结构排列呈128x128的形式,读取周期为0.5us,刷新周期为2ms,因此一个刷新周期中包含2ms/0.5us=4000个读取周期
- 集中刷新:如果采用2ms内集中安排时间全部刷新
- 系统的存取周期仍为0.5us,但有一段时间专门用于刷新,无法访问存储器,称为访存"死区"
- 那么2ms内有3872个周期(1936us)可用于读写,128个周期(64us)专门用于刷新
- 异步刷新:如果采用2ms内每行刷新1次即可
- 那么2ms内需要产生128次刷新请求用于对整个DRAM进行完整刷新,因此每行数据每隔2ms/128=15.6us必须要刷新一次,且每15.6us会产生0.5us的"死时间"
- 死时间相比集中刷新策略被分散开来,且可以利用CPU不访问存储器的时间进行刷新,如译码阶段
- 分散刷新:如果采用每次读写完就刷新一行
- 系统的存取周期变为1us,前0.5us用于读写,后0.5us用于刷新某行
- 那么在2ms内可以最多刷新2000行存储单元的信息
分散刷新可以避免出现访存"死区"
- 集中刷新:如果采用2ms内集中安排时间全部刷新
3.3.2 SRAM
静态RAM,Static Random Access Memory
- SRAM主要用于高速缓冲存储器Cache,与DRAM的存储元不一样,使用双稳态触发器存储信息,断电后信息消失
- 双稳态触发器共有6个MOS管,能够稳定的输出两种状态,需要两根数据线BL、BLX读出双稳态信息,分别接触A、B两个点。
- 读取数据时,当A输出高电平,B输出低电平时表示二进制1;当A输出低电平,B输出高电平时表示二进制0
- 双稳态触发器状态只要不发生断电均保持稳定,无需刷新。读出数据后,是非破坏性读出,无需重写,读写速度更快
- SRAM的存储容量较小,所需要的选通线比较少,因此行列地址一般同时送即可
- 每个存储元制造成本更高,集成度低,功耗大
3.3.3 地址线复用技术
对于n位的MAR,需要\(2^n\)根字选线/选通线,通过拆分为行、列地址的方式来减少译码器所接入的选通线,从而降低电路实现难度
DRAM由于存储容量较大,MAR传入的地址引脚较多
- 但由于行、列地址等长,可直接使用n/2根地址线,分别传入n/2长度的行/列地址到行/列地址缓冲器中
- 行、列地址分两次送,可使地址线更少,芯片引脚更少
扩展:
- 现代计算机主存储器已不采用SRAM、DRAM芯片,常采用SDRAM芯片如DDR3、DDR4
- SDRAM和DRAM的区别:
- 传统DRAM:
- 与CPU之间采用异步方式交换数据,CPU发出地址和控股之信号后,经过一段延迟时间,数据才读出或写入
- 在这段延迟时间里,CPU不断采样DRAM的完成信号,在没有完成之前,CPU只能处于等待状态而不能做其他工作
- SDRAM芯片:
- 其读写受系统时钟,即前端总线时钟CLK控制,与CPU之间采用同步方式交换数据
- 尽管SDRAM引入了DRAM,但是主体功能仍然采用电容实现,仍然需要进行刷新
- SDRAM的行缓冲器通常用SRAM实现
- 传统DRAM:
3.4 只读存储器ROM
RAM芯片具有易失性,断电后数据消失;ROM芯片具有非易失性,断电后数据不会丢失
ROM虽然英文是Read-Only Memory,但不代表所有ROM只支持读不支持写入数据功能,且有些ROM也同样具备RAM的随机存取的特性
3.4.1 常见ROM类型
MROM,Mask Read-Only Memory,掩模式只读存储器
- 厂家按照客户需求,在芯片生产过程中直接写入信息,之后任何人不可重写,只能读出
- 可靠性高、灵活性差、生产周期长、只适合批量定制
PROM,Programmable Read-Only Memory,可编程只读存储器
- 用户可用专门的PROM写入器写入信息,写一次之后就不可更改,和MROM一样也是只能读取数据
EPROM,Erasable Programmable Read-Only Memory,可擦除可编程只读存储器
- 允许用户写入信息,之后用某种方法擦除数据,可进行多次重写
- UVEPROM,ultraviolet rays,UV擦除可编程只读存储器
- 用紫外线照射8~20分钟,擦除所有信息
- 一次性擦除所有信息,无法选择部分擦除
- EEPROM,也常记为E\(^2\)PROM,第一个E是Electrically,电擦除可编程只读存储器
- 可用"电擦除"的方式,擦除特定的字
Flash Memory,闪速存储器,简称闪存
- U盘、SD卡就是闪存
- 闪存是在EEPROM基础上发展而来,断电后也能保存信息,且可进行多次快速擦除重写
- 由于闪存需要先擦除在写入,因此闪存的"写"速度要比"读"速度更慢,而读数据只需要直接读入即可
- 每个存储元只需单个MOS管,位密度比RAM高,所以单位体积的闪存容量比RAM更大
SSD,Solid State Drives,固态硬盘
- 由控制单元+存储单元/Flash芯片构成,与闪速存储器的核心区别在于控制单元不一样,但存储介质都类似,可进行多次快速擦除重写。
- SSD速度快、功耗低、价格高。目前个人电脑上常用SSD取代传统的机械硬盘
- 手机辅存也使用Flash芯片,但相比SSD使用的芯片集成度高、功耗低、价格贵
3.4.2 计算机中的ROM
当计算机断电重启,系统中RAM的数据会全部丢失,需要重新装载。在主板上有用一块BIOS芯片,这是一块ROM芯片,存储了"自举装入程序",负责引导装入操作系统(开机)
虽然通常意义上,主存一般单指RAM,即主板上的内存条。但实际上,主板BIOS的ROM芯片也是主存的一部分
在逻辑上,主存由RAM和BIOS的ROM组成,且二者常统一编址
- 如某计算机BIOS的ROM容量为1024B,按照字节编址,则主存地址0-1023B位置是ROM的空间,而RAM从1024B位置开始编址
3.5 解决主存与CPU速度不平衡
考虑到主存的存取周期包括存取时间和恢复时间,需要设置策略应对多核CPU同时访存的问题,以及主存的存取周期跟不上CPU读写速度的问题
3.5.1 双端口RAM(了解)
双端口RAM的设计用于优化多核CPU访问一根内存条的速度
- 需要有两组完全独立的数据线、地址线、控制线
- CPU、RAM中也要有更复杂的控制电路
两个端口对同一主存操作有以下4种情况:
- 两个端口同时对不同的地址单元存取数
- 两个端口同时对同一地址单元读出数据
- 两个端口同时对同一地址单元写入数据
- 两个端口同时对同一地址单元,一个写入数据,另一个读出数据
- 上述情况中,1、2是能够顺利工作的,而3可能会发生写入错误,4可能会发生读出错误,因此需要避免3、4情况的发生
- 置"忙"信号为0,由判断逻辑决定暂时关闭一个端口(即被延时),未被关闭的端口正常访问,被关闭的端口延长一个很短的时间段后再访问
- 3、4情况本质是资源争夺的情况,类比于操作系统中"读者-写者问题"
3.5.2 多模块存储器
通过多个模块的存储器组合乘一整个主存储器,解决主存的存取周期跟不上CPU读写速度的问题
多体并行存储器

多体并行存储器要求每个模块都有相同的容量和存取速度,各模块都有独立的读写控制电路、地址寄存器和数据寄存器。它们既能并行工作,又能交叉工作
对于多体并行存储器的编址有两种方式
- 高位交叉编址的多体存储:对于n位的MAR地址,其中高位中的k位作为区分存储体的编号,记为体号;剩余的n-k位标记该存储体内的第几个存储单元,记为体内地址,即MAR=体号+体内地址
- 低位交叉编址的多体存储:与高位交叉编址相反,低位作为体号,高位作为体内地址,即MAR=体内地址+体号
假设每个存储体的存取周期为T,存取时间为r,且T=4r,共有4个存储体\(M_0,M_1,M_2,M_3\),每个存储体的容量为8个存储单元
- 连续访问时,每次存取数据存储时间为r,恢复时间需要3r
- 如果连续访问00000B、00001B、00010B、00011B、00100B地址的数据时
- 对于高位交叉编址,所有数据都在同个存储体中,每读取一个数据就需要T的时间,存取完所有数据需要5T的时间
- 对于低位交叉编址
- 对于00000B地址的数据,CPU只需要花费r的时间进行存取,剩余3r时间CPU不需要访问,\(M_0\)自行进行恢复
- 而00001B已经准备好存取,CPU直接读取\(M_1\)即可
- 同理直到读取完\(M_3\)中00011B的数据后,此时\(M_0\)恢复时间已经结束,可以直接读取00100B地址的数据
- 综上所述,最终存取完所有数据只需要T+4r=2T的时间,其中包括了最后的恢复时间,如果只考虑读取数据时间只需要T+r的时间
- 因此,对于低位交叉编址,连续存取n个存储字,耗时T+(n-1)r的时间。从宏观层面,当n足够大时,单个字的读写时间接近于r

- 多体并行存储器的设计,采用流水行的方式并行存取,即宏观上并行,微观上串行
- 宏观上,一个存储周期内,m体交叉存储器可以提供的数据量为单个模块的m倍
- 存取周期为T,存取时间(或总线传输周期)为r,为了使流水线不间断,应保证模块数m ≥ T/r
- 总线传输周期:
- CPU从主存中读取数据的时间。不论表述为存储时间为r还是总线传输周期为r,都表明了CPU取到数据的实际时间大于等于r
- 多体交叉允许多个存储体进行数据读写,但是最终数据需要交给总线进行处理,而总线同时只能处理单个存储体,所以每个存储体采用分时策略占用总线将数据传输出去
- 为保证总线利用率最大,第一个存储体刷新恢复后,将数据交给总线传输,经过一个总线传输周期后,期望可以继续传输其他数据,因此将每个存储体的存取周期错开一个总线传输周期,保证总线无缝传输
- 同时由于处于刷新过程的存储体无法访存(存在死区),因此并行错开的存储体数m应该大于等于T/r
- 总线传输周期:
- 当m < T/r时,CPU需要额外等待存储体恢复
- 当m > T/r时,部分存储体会闲置,没有充分利用优势
- 只有当m=T/r时,可以无缝衔接让每个存储体不间断存取,其不存在闲置浪费
单体多字存储器

单体多字存储器指主存储器只是用一套单独的存储体,规定每个存储单元存储m个字,总线宽度也为m个字,一次并行读出m个字
- 每次只能同时取m个字,不能单独取其中的某个字,实现原理类似于位扩展
- 该种设计方式指令、数据在主存必须是连续存放的,并且读取过程中会存在无意义的数据读入,造成冗余浪费
如果频繁的使用跳转指令,会导致频繁读取冗余数据,造成工作效率降低
- 如果对于使用连续存储场景,读取冗余的数据,也确实缩短了整体读取的时间
单体多字存储器加快了存储的主存的读写速度(并行),但对主存的容量并未造成任何影响
3.5.3 多通道内存(扩展)
通俗说法的双通道。其实就是实现了低位交叉的多体存储器。主板上内存插槽中双通道的内存槽是成对出现的。而不遵循双通道方式插入内存条,只是进行了单纯的内存扩容,属于高位交叉的多体存储器
- 为了实现双通道,需要挑选相同主频、相同容量的内存组成双通道
- 主频相同的内存相当于内存存取周期时间是相同的,如果组成双通道的两条内存条主频不同,频率较高的内存会进行降频达到相同主频的组合
- 如果组成双通道的两条内存容量不同,只有相同长度部分可能可以组成双通道,且该状态很不稳定。当数据存放在相同长度部分时读取会快,而剩余部分只能作为单通道,读取速度偏慢
3.6 存储器与CPU的连接
现代计算机将MAR、MDR集成在CPU中,存储芯片内只需要一个普通寄存器暂存输入、输出数据即可
存储芯片中将地址线信号记为\(A_i\)(i=1,2,...,k),数据线信号记为\(D_i\)(i=1,2,...,j),片选线信号记为\(\overline{\text{CS}}\)或\(\overline{\text{CE}}\),读/写控制线信号记为\(\overline{\text{WE}}\)或\(\overline{\text{WR}}\)
同理,CPU的地址线信号也记为\(A_i\)(i=1,2,...,n),数据线信号记为\(D_i\)(i=1,2,...,m),读写控制线信号\(\overline{\text{WE}}\)或\(\overline{\text{WR}}\)
对于单块存储芯片与CPU连接,要求数据总线宽度 = 存储字长,一般机器字长和数据总线宽度相同。但由于存储芯片设计的规格并不是全部按照机器字长设计的,需要调整才能与CPU连接
不可能设计存储字长>机器字长的存储芯片,一般默认存储字长小于机器字长
3.6.1 主存字长扩展:位扩展
当采用的存储芯片与CPU连接时,数据总线宽度 > 存储芯片字长,可通过增加存储芯片的数量来让数据位数与存储字长位数相同
假设某块存储芯片规格为8k x 1位,CPU的MAR为16位,MDR位8位,读写信号为\(\overline{\text{WE}}\),片选信号为\(\overline{\text{CS}}\)
- 该存储芯片容量为\(2^{13}\) bit,地址线共13根,数据线为1根,显然与CPU的MAR、MDR不相匹配
- 扩展8块该存储芯片,使得数据位扩展为8位,CPU的读写线WE与8块存储芯片同时相连,CPU数据线分别于8块芯片的数据线相连,CPU的地址线\(A_0\) ~ \(A_12\)同时与8块芯片相连。每一块存储芯片的
目前MAR只用到了低位地址,且每块芯片都需要使用,因此片选线信号\(\overline{\text{CS}}\)输入低电平,表示选中。因此MAR的高位全部置为0
- 因此最终将8块该存储芯片扩展为一个8k x 8bit,容量位8KB的存储芯片
3.6.2 主存容量扩展:字扩展
当需要采用多块相同规格存储芯片与CPU连接时,数据总线宽度=单个芯片存储芯片字长,但单个芯片地址线数 < 地址总线宽度
- 如果此时所有芯片的片选信号都接通表示选中的话,CPU在读取数据时会发生冲突,需要调整片选信号告知CPU目前读取哪块存储芯片的数据
假设某块存储芯片规格为8k x 8位,CPU的MAR为16位,MDR位8位
-
该存储芯片容量为\(2^{13}\) bit,地址线共13根,数据线为8根,与CPU的MDR相匹配,但与MAR不匹配
-
由于需要使用多块该存储芯片,需要告知CPU选择哪块芯片进行读写
- 线选法:由于目前还剩余\(A_{13},A_{14},A_{15}\)三根地址线未使用,可以将三根地址线分别接在需要连接的存储芯片上,选中哪块芯片其片选信号\(\overline{\text{CS}}\)为低电平,其余均为高电平
该种方法n个片选信号只能最多控制n块芯片,虽然电路实现简单,但片选信号存在浪费,且地址空间不连续
- 译码器片选法:通过译码器,将n根片选线信号转换为\(2^n\)中片选信号,从而支持最多控制\(2^n\)个存储芯片
由于片选信号为\(\overline{\text{CS}}\),只需要在每个存储芯片片选信号输入端加一个非门即可
当所连接的存储芯片数量较少时,可以只接入部分地址线,防止多个地址映射同一个芯片的存储单元造成浪费,保证有效地址空间连续
3.6.3 字、位同时扩展
数据位由多块存储芯片为一组进行数据位扩展,同时进行多组片选容量扩展
这样存储芯片的地址就划分为MAR = 片选号 + 组内序号,且地址空间从0000H地址连续递增
3.6.4 译码器
译码器可将n位的信号转换为\(2^n\)的信号,且输入信号只有一个位为高电平,其余均为低电平
译码器的输出信号除了自上而下编号,也可以逆序进行编号
- 如1-2译码器可以将1位信号转换为01、10两种情况,3-8译码器可以将1位信号转换为10000000、01000000、00100000、00010000、00001000、00000100、00000010、00000001八种情况
译码器除了接受的n位片选信号以及输出的\(2^n\)信号外,可能还包含使能信号,让CPU在使用译码器时,控制片选信号的生效时间
- 如译码器74ls138型号,是一个3-8译码器,输出端处具有非门电路。同时,它包含\(G_1\)、\(\overline{G_{2A}}\)、\(\overline{G_{2B}}\)三个使能信号
- CPU除了MAR、MDR、WE信号以外,还有一个主存储器请求信号\(\overline{\text{MREQ}}\),Memory Request。当CPU想要访问存储时,该信号会输出低电平表示有效
CPU与存储器连接过程:
- CPU线通过地址总线将地址信号传给译码器以及存储器
- 由于传入过程电压不稳定,需要等待地址信号稳定后才发出存储器请求信号,让\(\overline{\text{MREQ}}\)输出低电平,输入到\(\overline{G_{2B}}\)处,告知译码器当前片选信号输出有效
- 此时,主存储器才得知真正需要访存的地址
RAM的读周期

- 再上图中节点阶段变化过程中,发现并非直线而是斜线,表示该时间内信号可能是0,可能是1,处于信号不稳定状态
3.7 外存储器
外存储器又称为辅助存储器,目前主要使用磁表面存储器
- 外存储器既可以作为输入设备,也可以作为输出设备。既可以存数据,也可以读数据
3.7.1 磁盘存储器
将某些磁性材料薄薄地按圈涂在金属铝或塑料表面上作为载磁
体来存储信息。磁盘存储器、磁带存储器和磁鼓存储器均属于磁表面存储器
- 工作原理:当磁头和磁性记录介质有相对运动时,通过电磁转换完成读/写操作
- 编码方法:按某种方案(规律),把一连串的二进制信息变换成存储介质磁层中一个磁化翻转状态的序列,并使读/写控制电路容易、可靠地实现转换
- 磁记录方式:通常采用调频制(FM)和改进型调频制(MFM)的记录方式
- 优点:
- 存储容量大,位价格低
- 记录介质可以重复使用
- 记录信息可以长期保存而不丢失,甚至可以脱机存档
- 非破坏性读出,读出时不需要再生
- 缺点:
- 存取速度慢
- 机械结构复杂
- 对工作环境要求较高,遇到强磁场环境可能会造成信息丢失
磁盘存储器组成
存储区域:
-
一块硬盘含有若干个记录面,每个记录面划分为若干条磁道,而每条磁道又划分为若干个扇区,扇区(也称块)是磁盘读写的最小单位,也就是说磁盘按块存取
- 磁头数,Heads,即记录面数,表示硬盘总共有多少个磁头,磁头用于读取/写入盘片上记录面的信息,一个记录面对应一个磁头
一般在盘片的两面都会涂上磁性材料,因此磁头会有上下两个触点,用于读取上线面的数据
但最上方以及最下方的磁面不使用,即n个盘片仅使用2(n-1)个盘面/记录面
- 柱面数,Cylinders,表示硬盘每一面盘片上有多少条磁道。在一个盘组中,不同记录面的相同编号(位置)的诸磁道构成一个圆柱面
- 扇区数,Sectors,表示每一条磁道上有多少个扇区
磁盘都是按照扇区进行读写操作的
硬盘存储器:
- 由磁盘驱动器、磁盘控制器和盘片组成
- 磁盘驱动器:核心部件是磁头组件和盘片组件,温彻斯特盘是一种可移动头固定盘片的硬盘存储器
控制磁头的移动,选择不同的磁道以及扇区
- 磁盘控制器:是硬盘存储器和主机的接口,主流的标准有IDE、SCSI、SATA等
磁盘工作过程:
- CPU提供给磁盘控制器一个逻辑地址,该逻辑地址格式和具体的操作系统的磁盘资源管理方式有关
- 磁盘控制器通过逻辑地址将对应的物理地址,即柱面号/磁道号、盘面号、扇区号,传递给磁盘驱动器
- 磁盘驱动器通过提供的物理地址信息驱动磁头移动到地址的所在位置
磁盘的性能指标
磁盘存取的完整步骤:
- 启动磁头:存在启动驱动器的时延
- 查找磁道:存在寻道时间,该寻道指盘沿着半径向内向外的移动时间
- 查找扇区:存在旋转延迟时间,磁盘的转速越高,旋转延迟时间越短
- 数据传输:存在传输延迟时间,一般包含扫描多个扇区一并传输的时间
磁盘的容量:
- 一个磁盘所能存储的字节总数称为磁盘容量
- 磁盘容量有非格式化容量和格式化容量之分
- 生产厂商一般会设定格式化后才能使用磁盘,格式化过程会留下一部分备用空间,避免盘片发生物理损坏还能继续使用
- 非格式化容量是指磁记录表面可以利用的磁化单元总数
- 格式化容量是指按照某种特定的记录格式所能存储信息的总量
记录密度:
- 记录密度是指盘片单位面积上记录的二进制的信息量,通常以道密度、位密度和面密度表示
- 道密度是沿磁盘半径方向单位长度上的磁道数,单位如道/cm
- 位密度是磁道单位长度上能记录的二进制代码位数,单位如bit/cm
磁盘所有磁道记录的信息量一定是相等的,并不是圆越大信息越多,故每个磁道的位密度都不同
磁盘的容量很大程度取决于内侧磁道位密度,位密度越大,制作工艺难度越大,磁盘整体造价也越高
因此越靠近盘片内侧的磁道位密度越大,遇到损坏丢失的数据越多
- 面密度是位密度和道密度的乘积
平均存取时间 = 寻道时间 + 旋转延迟时间 + 传输时间
- 寻道时间:磁头移动到目的磁道
- 旋转延迟时间:磁头定位到所在扇区,平均时间为磁头旋转半圈的时间
- 传输时间:传输数据所花费的时间
- 有些磁盘传输数据前存在磁盘控制器延迟,如果题目中有提及需要统计到存取时间中
数据传输率:
- 磁盘存储器在单位时间内向主机传送数据的字节数,称为数据传输率
- 假设磁盘转数为r(转/秒),每条磁道容量为N个字节,则数据传输率为D\(_r\) = r x N
磁盘地址:
- 主机向磁盘控制器发送寻址信息,磁盘的地址一般由驱动器号 + 柱面/磁道号 + 盘面号 + 扇区号组成
- 驱动号指明使用哪个磁盘,因为一台电脑可能有多个磁盘
- 磁道号指明移动磁头臂(寻道)停留的位置
- 盘面号指明激活哪个盘面上的磁头
- 扇区号指明通过旋转磁头划过的特定扇区位置
- 若系统中有4个驱动器,每个驱动器带一个磁盘,每个磁盘256个磁道、16个盘面,每个盘面划分为16个扇区,则每个扇区地址需要18位二进制代码
- 驱动器号占2bit,柱面/磁道号占8bit,盘面号占4bit,扇区号占4bit

硬盘的工作过程:
- 硬盘的主要操作是寻址、读盘、写盘。每个操作都对应一个控制字,硬盘工作时,第一步是取控制字,第二步是执行控制字
- 硬盘属于机械式部件,其读写操作是串行的,不可能在同一时刻既读又写,也不可能在同一时刻读两组数据或写两组数据
- 接收到来自总线的并行数据需要转化为串行数据一个个二进制位处理,分别执行读或写操作
- 数据进行读入时,磁盘读入过程是串行的,需要将串行数据转换为并行数据再送给总线
- 磁盘按照批处理的方式对数据进行读写操作,尽管实际上只对一个块进行读写,也是以扇区为单位进行批量读写
磁盘阵列
RAID,Redundant Array of Inexpensive Disks,廉价冗余磁盘阵列
- 将多个独立的物理磁盘组成一个独立的逻辑盘,数据在多个物理盘上分割交叉存储、并行访问,具有更好的存储性能、可靠性和安全性
- RAID由多个分级,
- RAID0:无冗余和无校验的磁盘阵列
- 逻辑上相邻的两个扇区在物理上存到两个磁盘,类比第三章"低位交叉编址的多体存储器"。该种方案可以时数据进行并行访问,加快磁盘读写速度
- RAID0把连续多个数据块交替地存放在不同物理磁盘的扇区中,几个磁盘交叉并行读写,不仅扩大了存储容量,而且提高了磁盘数据存取速度,但RAID0没有容错能力
- RAID1:镜像磁盘阵列
- RAID1是为了提高可靠性,使两个磁盘同时进行读写,互为备份,如果一个磁盘出现故障,可从另一磁盘中读出数据。两个磁盘当一个磁盘使用,意味着容量减少一半
- RAID2:采用纠错的海明码的磁盘阵列
- 逻辑上连续的几个bit物理上分散存储在各个盘中4bit信息位 + 3bit海明校验位,该种方式可纠正一位错误
- RAID3:位交叉奇偶校验的磁盘阵列
- RAID4:块交叉奇偶校验的磁盘阵列
- RAID5:无独立校验的奇偶校验磁盘阵列
- RAID0:无冗余和无校验的磁盘阵列
- 其中,RAID1~RAID5物种方案,无论何时有磁盘损坏,都可以随时拔出受损的磁盘再插入好的磁盘,而数据不会损坏
RAID磁盘阵列
- 通过同时使用多个磁盘,提高了传输率
- 通过在多个磁盘上并行存取来大幅提高存储系统的数据吞吐量
- 通过镜像功能,可以提高安全可靠性;通过数据校验,可以提供容错能力
3.7.2 固态硬盘SSD
固态硬盘,SSD,Solid State Drives
- 原理:SSD基于闪存技术Flash Memory,属于电可擦除ROM,即EEPROM
- 由闪存翻译层、存储介质组成
- 闪存翻译层:负责翻译逻辑块号,找到对应的页Page
- 存储介质:和闪存类似,一般是多个闪存芯片Flash Chip。每个芯片包含多个块block,每个块包含页page
SSD读写性能特性
- 以页page为单位的读/写,相当于磁盘的扇区读写
- 以块block为单位擦除,其中的每页都可以写一次,读无限次
- SSD支持随机访问,系统给定一个逻辑地址,闪存翻译层可通过电路迅速定位到对应的物理地址
- SSD的读取数据速度快,但写入数据慢。要写的页如果有数据则不能直接写入,需要将块内的其他页全部复制到一个新的或者擦除过的块中,再写入新的页
- 一个数据存放的实际物理位置可能会变化,但是操作系统层面使用的逻辑块号对应到新物理地址过程全部由闪存翻译层完成,因此操作系统对物理地址的变化完全透明
SSD与机械硬盘的区别
- SSD读写速度快,随机访问性能高,用电路控制访问位置;而机械硬盘通过移动磁臂旋转磁盘控制访问位置,由寻道时间和旋转延迟
- 固态硬盘的实际的读写单位为页page,在操作系统层面读写单位使用的是逻辑块;而磁盘的读写单位为扇区/块,固态硬盘和磁盘的块的概念并不相同
- SSD安静无噪声,耐摔抗震,能耗低,造假相比机械硬盘更贵
- SSD一个块备擦除次数过多或者重复写入同一个块过多次数,可能会坏块且无法修复;机械硬盘扇区不糊因为写入次数太多而坏掉,只会因为物理损坏而坏块
磨损均衡技术
将SSD的擦除平均分布在各个块上,以提升SSD的使用寿命
动态磨损均衡:写入数据时,优先选择累计擦除次数少的新闪存块
静态磨损均衡:SSD监测并自动进行数据分配、迁移,让老旧的闪存块承担以读为主的存储任务,让较新的内存块承接更多的写任务
SSD的寿命
某固态硬盘采用磨损均衡技术,大小为240B=1TB,闪存块的擦写寿命只有210=1K次。某男子
平均每天会对该固态硬盘写237B=128GB数据。在最理想的情况下,这个固态硬盘可以用多久?
- SSD采用磨损均衡技术,最理想情况下,SSD中每个块被擦除的次数都是完全均衡的
- 1TB/128GB=8,即平均每8天,每个闪存块需要擦除一次
- 每个闪存块可以被擦除1K次,因此,经过8K天,约23年后,该固态硬盘被男子玩坏
3.8 Cache基本原理
尽管双端口RAM、多模块存储器设计可以提高存储器的工作速度,但速度上与CPU的差距依旧很大
- 如果设计更高速的存储单元,价格成本会更高,容量也会更低
- 考虑程序访问的局部性原理,可使用Cache+主存的双层结构改善与CPU速度不匹配的问题
- 程序访问的局部性原理
- 空间局部性:在最近的未来要用到的信息(指令和数据),很可能与现在正在使用的信息在存储空间上是邻近的
- 时间局部性:在最近的未来要用到的信息,很可能是现在正在使用的信息
- 程序并不是所有代码片段一直都在访问,在一段时间内只有一部分代码片段会反复执行
- 基于局部性原理,不难想到,可以把CPU目前访问的地址"周围"的部分数据放到Cache中
- 程序访问的局部性原理
实际上,Cache被集成在CPU内部,Cache用SRAM实现,速度快,成本高
性能分析:
- 设\(t_c\)为访问一次Cache所需时间,\(t_m\)为访问一次主存所需时间
- 命中率H:CPU欲访问的信息已在Cache中的比率
- 缺失(未命中)率M = 1 - H
- Cache — 主存系统的平均访问时间t
- 采取先访问Cache,若Cache未命中再访问主存的方案,耗时为H x \(t_c\) + (1 − H) x (\(t_c\) + \(t_m\))
- 采取同时访问Cache和主存,若Cache命中则立即停止访问主存的方案,耗时为H x \(t_c\) + (1 − H) x \(t_m\)
一般情况下,主存的块大小不会选择很大,也不会很小
- 如果主存块过小,块会过于离散,无法利用空间局部性,直接导致缺失率提高
- 如果主存块过大,Cache行数减少,极限角度只剩一行Cache,但是Cache容量远小于主存容量,必然导致缺失率提高
假设Cache的速度是主存的5倍,且Cache的命中率为95%,则采用Cache后,存储器性能提高多少?(设Cache和主存同时被访问,若Cache命中则中断访问主存)
- 设Cache的存取周期为t,则主存的存取周期为5t
- 若Cache和主存同时访问,命中时访问时间为t,未命中时访问时间为5
- 平均访问时间为 0.95×t+0.05×5t=1.2t
- 故性能为原来的 5t/1.2t ≈ 4.17倍
- 若先访问Cache再访问主存,命中时访问时间为t,未命中时访问时间为t+5t
- 平均访问时间为\(T_a\) = 0.95×t+0.05×6t=1.25t
- 故性能为原来的 5t/1.25t=4倍
3.8.1 Cache与存储映射方式
基于局部性原理,CPU可以将目前访问地址周围的部分数据放到Cache中加快读写,对于需要移入到Cache中的数据范围需要讨论
- 将主存的存储空间"分块",如:每1KB 为一块。那么,主存与Cache之间以"块"为单位进行数据交换
- 假设Cache的一个块为8KB,而主存大小为4MB,则主存被划分为\(2^{22}\)/\(2^{10}\)=4096块
- 操作系统中,通常将主存中的"一个块"也称为"一个页/页面/页框"。而Cache中的"块"也称为"行"
- 每次被访问的主存块,一定会被立即调入Cache
- 给每个Cache块增加一个"有效位"以及"标记",记录对应主存块号
由于Cache的块和主存的块等大,因此主存地址块内地址长度和Cache地址长度等长
全相联映射方式
主存块可以放在Cache的任意位置
假设某个计算机的主存地址空间大小为256MB,按字节编址,其数据Cache有8个Cache行,行长为64B
- Cache行即Cache块,与主存块的大小相等,因此Cache大小共为8x64B=\(2^9\)B
- 主存块大小和Cache等大,因此主存共有256MB/64B=\(2^{27}\)B / \(2^6\)B= \(2^{22}\)块
- 主存共256MB=\(2^{28}\)B,因此一个MAR地址占用28位二进制,而主存块号需要占用22位地址
- 即28位的MAR = 22位的主存块号 + 6位的块内地址
全相联映射过程
- Cache初始状态所有有效位置0,当与主存进行块交换时,全相联映射是任意位置放置,假设就按顺序放置,则对应位置的块有效位修改为1,标记存放主存块号
- 假设CPU要访问内存的1...1101001110B 地址,先取该地址的前22位主存块号,比对Cache所有块的标记
- 若标记匹配且有效位=1,则Cache命中,访问块内地址为001110 的单元
- 若未命中或有效位=0,则正常访问主存
全相联映射方式主存地址构成:
| 主存块号 | 块内地址 |
|---|
直接映射方式
每个主存块只能放到一个特定的位置,Cache块号=主存块号 % Cache总块数
假设假设某个计算机的主存地址空间大小为256MB,按字节编址,其数据Cache有8个Cache行,行长为64B
- CPU访问主存后需要将对应块交换到Cache内,如交换0号块时,0%8=0,则存放到Cache的0编号位置,并修改有效位为1,将标记为设置为0
- 假设此时又需要与主存的8号块进行交换,8%8=0,则仍然需要存放到Cache的0编号位置,不论0编号是否存放过数据,都进行覆盖
- 很显然,直接映射相比全相联映射,块交换的位置更加有次序,但是由于采用取余的方式,尽管其余位置是空闲的,也不能使用
- 同时,假设主存块数为\(2^m\),Cache总块数为\(2^n\),由于主存块在Cache中的位置为主存块号%\(2^n\),则标记的末尾n位均为Cache的块内位置,可以省略。因此可优化标记只需要存放m-n位即可
直接映射过程
- 假设CPU要访问内存的1...1101001110B 地址,根据主存块号的后3位确定Cache行
- 若主存块号的前19位与Cache标记匹配且有效位=1,则Cache命中,访问块内地址为001110B 的单元
- 若未命中或有效位=0,则正常访问主存
直接映射方式主存地址构成:
| 主存块号 | 主存块号 | 块内地址 |
|---|---|---|
| 标记位 | Cache字块地址 | 块内地址 |
组相联映射方式
Cache块分为若干组,每个主存块可放到特定分组中的任意一个位置,组号=主存块号 % 分组数
- 2路组相联映射:2块为一组
假设某个计算机的主存地址空间大小为256MB,按字节编址,其数据Cache有8个Cache行,行长为64B,假设采用2路组相联映射
- 类似于直接相联映射,主存块号的最后两位作为组号,标记只需要存放20位即可
组相联映射过程
- 假设CPU要访问内存的1...1101001110B 地址,根据主存块号的后2位确定所属分组号
- 若主存块号的前20位与分组内的某个标记匹配且有效位=1,则Cache命中,访问块内地址为001110的单元
- 若未命中或有效位=0,则正常访问主存
组相联映射方式主存地址构成:
| 主存块号 | 主存块号 | 块内地址 |
|---|---|---|
| 标记位 | Cache所在组号 | 块内地址 |
映射方式例题
某计算机有容量为256B的数据Cache,主存块大小为32B,现有如下代码
int i,j,c,s,a[128];
for(i=0;i<10000;i++)
for(j=0;j<128;j=j+s)
c=a[j];
int型数用32补码表示,编译器将变量i,j,c,s都分配在通用寄存器中,因此只需考虑数组元素访存情况,假定数组起始地址正好在一个主存块的开始
- 256B容量的Cache,块大小为32B,共256/32=8个块,一个块可存放32/4=8个数组a元素
- 若Cache采用直接映射,当s=64和s=63时缺失率分别为多少
-
直接映射,数组a元素存放在Cache中的位置
Cache块号 数组元素 数组元素 0 0-7 64-71 1 8-15 72-79 2 16-23 80-87 3 24-31 88-95 4 32-39 96-103 5 40-47 104-111 6 48-55 112-119 7 56-63 120-127 -
s=64时,只访问a[0],a[64]两个元素,循环10000次
- 每轮访问a[64]都要覆盖Cache 0行位置的a[0],导致每次都缺失,缺失率=100%
-
s=63时,只访问a[0],a[63],a[126]三个元素,循环10000次
- 每轮访问a[126]后会覆盖Cache 7行位置a[63],导致每轮2次,即缺失率=2/3=66.7%
-
- 若Cache采用2-路组相联映射,当s=64和s=63时,缺失率分别为多少
-
2-路组相联,数组a元素存放在Cache中的位置
Cache组号 数组元素 数组元素 数组元素 数组元素 0 0-7 32-39 64-71 96-103 1 8-15 40-47 72-79 104-111 2 16-23 48-55 80-87 112-119 3 24-31 56-63 88-95 120-127 -
s=64时,只访问a[0],a[64]两个元素,循环10000次
- 第一轮访问a[0],a[64]放入Cache 0组位置,均发生缺失,后续循环均命中,缺失率为0.01%
-
s=63时,只访问a[0],a[64]两个元素,循环10000次
- 第一轮访问a[0]放入Cache 0组,a[63]放入Cache 3组,a[126]放入Cache 3组,均发生缺失,后续循环均命中,缺失率为0.015%
-
3.8.2 Cache替换算法
由于Cache 很小,主存很大,频繁的主存访问必然需要考虑将Cache内的老数据进行替换
- 对于全相联映射,Cache完全满了才需要替换需要在全局选择替换哪一块
- 对于直接相联映射,如果对应位置非空,则毫无选择地直接替换,因此直接相联映射不需要考虑替换算法
- 对于组相联映射,分组内满了才需要替换需要在分组内选择替换哪一块
随机替换算法RAND
随机算法,RAND, Random
- 若Cache已满,则随机选择一块替换
- 实现简单,但完全没考虑局部性原理,命中率低,实际效果很不稳
先进先出替换算法FIFO
先进先出算法,FIFO, First In First Out
- 若Cache已满,则替换最先被调入Cache 的块
- 实现简单,最开始按#0#1#2#3放入Cache,之后轮流替换#0#1#2#3,但FIFO依然没考虑局部性原理,最先被调入Cache的块也有可能是被频繁访问
- 抖动现象:频繁的换入换出现象,刚被替换的块很快又被调入
FIFO算还需要额外记录每个Cache行的时间戳,用于将最早放入Cache块换出
近期最少使用替换算法LRU
近期最少使用算法,LRU, Least Recently Used
- 为每一个Cache块设置一个"计数器",用于记录每个Cache块已经有多久没被访问了。当Cache满后替换"计数器"最大的
- Cache命中时,所命中的行的计数器清零,比其低的计数器加1,其余不变
- 未命中且还有空闲行时,新装入的行的计数器置0,其余非空闲行全加1
- 未命中且无空闲行时,计数值最大的行的信息块被淘汰,新装行的块的计数器置0,其余全加1
- Cache块的总数=\(2^n\),则计数器只需n位,且Cache装满后所有计数器的值一定不重复
- 如果采用组相联映射方式,计数器所需位数只与组数有关,假设为\(2^k\)-路组相联,则计数器需要k位
- 基于局部性原理,近期被访问过的主存块,在不久的将来也很有可能被再次访问,因此淘汰最久没被访问过的块是合理的
- LRU算法的实际运行效果优秀,Cache命中率高。若被频繁访问的主存块数量> Cache行的数量,则有可能发生抖动,如:
最不经常使用替换算法LFU
最不经常使用算法,LFU, Least Frequently Used
- 为每一个Cache块设置一个"计数器",用于记录每个Cache块被访问过几次。当Cache满后替换"计数器"最小的
- 新调入的块计数器=0,之后每被访问一次计数器+1。需要替换时,选择计数器最小的一行
- 若有多个计数器最小的行,可按行号递增、或FIFO策略进行选择
- 曾经被经常访问的主存块在未来不一定会用到(如:微信视频聊天相关的块),并没有很好地遵循局部性原理,因此实际运行效果不如LRU
3.8.3 Cache写策略/更新策略
CPU修改了Cache中的数据副本,会出现Cache中的副本需要与主存的数据不一致的情况,需要设定策略保持一致
- 对于CPu的读操作,是否在Cache中命中并不影响与主存中一致性的问题
命中写操作策略
写回/回写法,write-back:
- 当CPU对Cache写命中时,只修改Cache的内容,而不立即写入主存,只有当此块被换出时才写回主存
- 由于未被修改的块不必写回,因此Cache中还需要增加脏位标志位,表示是否被修改过
- 该种策略减少了访存次数,但存在数据不一致的隐患
全写法,也叫写直通法,write-through:
- 当CPU对Cache写命中时,必须把数据同时写入Cache和主存,一般使用写缓冲(write buffer)
- 写缓冲通常用SRAM实现,是一个FIFO队列,写入速度比主存快得多
- 当CPU向Cache写入数据后,会同时向写缓冲内写入数据;当CPU空闲状态,在专门的控制电路控制系啊,会将写缓冲中的数据逐一写回主存
- 使用写缓冲,CPU写的速度很快,若写操作不频繁,则效果很好。若写操作很频繁,可能会因为写缓冲饱和而发生阻塞
- Cache块被替换时无需写回,因此也不需要使用脏位标志位
- 该种策略访存次数增加,速度变慢,但更能保证数据一致
不命中写操作策略
写分配法,write-allocate:
- 当CPU对Cache写不命中时,把主存中的块调入Cache,在Cache中修改。通常搭配写回法使用
非写分配法,not-write-allocate:
- 当CPU对Cache写不命中时只写入主存,不调入Cache。通常搭配全写法使用
- 只有当CPU发生"读"未命中时才调入Cache
3.8.4 Cache容量计算
Cache中每行存储数据部分以及控制部分,因而Cache的总容量= 数据部分 + 控制部分
- 数据部分大小 = Cache行数 x 块大小
- 控制部分大小 = Cache行数 x ( 标记位(视映射方式而定) + 有效位(1 bit) + 算法位(视算法而定) + 脏位(1 bit) )
- 映射方式影响需要多少位的标记位
- 全相联映射,随机放,标记位和主存快号长度相同
- 直接映射,取模散列,假定Cache共2\(^n\)块,主存块号共m位,标记位取主存块号高m-n位
- k路组相联映射,假定Cache划分为2\(^n\)个分组,主存块号共m个,标记位取主存块号高m-n
- 替换算法影响是否需要算法位
- 采用的Cache写策略影响是否需要脏位
- 映射方式影响需要多少位的标记位
对于Cache的行数 x 控制部分大小,仅仅表示地址映射表的大小
直接映射方式:
- 主存地址被划分为三部分:主存字块标记 + Cache字块地址 + 字块内地址
- 其中,直接映射,主存在Cache的位置固定为主存块号%Cache总块数
- 考虑到一般块大小位数远大于控制部分信息位,主存容量与Cache容量的比值近似为主存行数与Cache行数的比值
- 若假设比值为2\(^n\),则主存字块标记位数为n
3.8.5 多级Cache
现代计算机通常采用多级Cache,离CPU越近速度越快,容量越小;离CPU越远速度越慢,容量越大
- 各级Cache之间也需要进行内存映射,也同样存在一致性问题
- 各级Cache之间常采用"全写法+非写分配法",而Cache-主存之间常采用"写回法+写分配法"
使用多级Cache时,如果1、2低级Cache未命中,到高级Cache中查找过程不属于未命中状态,依旧在Cache内查找,查找时间依旧比到主存查找时间短
3.9 虚拟存储器(见操作系统23)
由于虚拟存储器是介于主存和辅存/磁盘之间的虚拟概念
- 虚拟存储访问的逻辑地址和存储器的物理地址的对应关系通过硬件的地址译码器(地址翻译)以及操作系统(资源管理)共同管理
- 虚拟存储器对于应用级程序员透明,对于操作系统级程序原不透明
本文来自博客园,作者:GK_Jerry,转载请注明原文链接:https://www.cnblogs.com/GKJerry/articles/18329230

浙公网安备 33010602011771号