参考了王道和几个博主的博客,自己使用的学习笔记
存储系统
3.1 基本概念
计算机的存储系统包括cpu内部寄存器,Cache,主存和外存。
知识总览:
1.存储器的层次结构
存储器层次结构的主要思想就是上一层的存储器作为低一层存储器的告诉缓存。
主存——辅存:解决了主存容量不够的问题。主存和辅存之间的数据调动是由硬件和操作系统共同完成,对应用程序员是透明的。
Cache——主存:解决了主存与CPU之间速度不匹配的问题。主存和cache层之间的数据调动是由硬件自动完成,对所有程序员都透明。
2.存储器的分类
(1)按作用分类
- 主存储器:主存,内存储器
- 辅助存储器:辅存,外存储器或外存(可以永久的保存信息)
- 高速缓冲存储器:cache,位于主存和cpu之间
(2)按存取方式进行分类
- 随机存储器(RAM):读写任何一个存储单元所需的时间都相同,与位置无关。
- 只读存储器(ROM):存储器内容只随机读而不能写。(断电不丢失)
- 串行访问寄存器:对存储单元进行读写操作时,需要按照物理地址的先后顺序寻址,包含顺序存取存储器(SAM,如磁带)和直接存取存储器。(DAM,如磁盘,光盘)
- 相连存储器(CAM):可按内容访问的存储器。(块表)
(3)按信息的可保存性进行分类
- 易失性存储器:断电后数据消失(RAM,主存,Cache)
- 非易失性存储器:断电依然保存(磁盘、光盘)
- 破坏性读出:读出数据后要进行重写(如DRAM芯片)
- 非破坏性读出:读出数据后原数据没被破坏(如SRAM芯片、磁盘、光盘)
(4)按存储介质分类
磁表面存储器(磁带,磁盘),磁芯存储器,半导体存储器(MOS型存储器,双极型存储器)和光存储器(光盘)。
3.存储器的性能指标(重要)
- 存储容量:存储字数 x 存储字长(如 1M x 8bit =1MB)。
MAR反映存储字数,MDR反映了存储字长。
-
单位成本:每位价格 = 总成本/总容量(某条内存条价格为259,容量为8GB,则单位成本 = 259 / (8*8) )。
-
存储速度:数据传输率 = 数据的宽度/存储周期
-
存取时间:存取时间 + 恢复时间 = 存取周期,计算机进行一次读写操作后需要一段恢复时间才能进行下一次的读写操作。
-
存取周期:指存储器进行一次完整的读/写操作所需要的全部时间(存储器进行连续读/写所允许的最短时间间隔)
-
主存带宽:就是上面的数据传输率,表示每秒从主存进出信息的最大数量,单位为字/秒,字节/秒,位/秒。
3.2主存储器
3.2.1主存储器的基本组成
知识总览:
(1)存储体
存储体由多个存储单元构成,每个存储单元由多个存储元构成。
存储元:能够存储一位比特。
电容:存储电荷,有电压差表示比特1,无电压差表示比特0。
MOS管:一个电控开关,当输入电压到达某个阀值时,MOS管就可以接通,电容中的电荷就可以跑出来。(相当于一个电路的开关)
将多个存储元组合起来就构成了存储单元,同个存储单元的存储元共用一根MOS管。
将多个存储单元组合起来就构成了存储体。
(2)地址寄存器和数据寄存器
通过 译码器来选择哪一个存储单元进行读写。
并通过数据总线传送数据。
(3)控制电路:
控制电路控制着 MAR,译码器和MDR的数据处理。
MDR的位数与数据线的位数相同,MAR的位数与地址线的位数相同。(重要)
同时存储芯片还需要对外提供 片选线,读选择线,写选择线。
片选线:芯片的总开关,低电平有效时表示选择了这块芯片进行工作了。
读选择线,写选择线:分别用来控制是读还是写。有时候会将这两根线合为一条,用低电平表示写,用高电平表示读。
(4)从总体上来看:
这里也表明了片选线的作用,上述的内存条是由多个存储芯片构成,假设每个存储芯片为1GB,则这条内存条条就为8GB,在进行读写数据时,需要通过片选线来选取不同的存储芯片进行存储。
寻址:
假设该存储体中的存储字长为4B,总容量为1KB,则存储单元为256个。
寻址方式可分为四种:
- 按字节寻址:则有1K个地址,需要10根地址线
- 按字寻址:则有256个地址,字节地址等于字地址乘于字长。
- 按半字寻址
- 按双字寻址
3.2.2 随机存取存储器RAM
RAM主要分为两种:
SRAM:存储单元是双稳态触发器,静态RAM,用于Cache
DRAM:存储单元是栅极电容动态RAM,用于主存
其主要区别:
DRAM的存储速度比SRAM的慢,且必须定时刷新和读后再生。
DRAM上的电容的电荷一般只能维持2ms (刷新周期),所以需要定时刷新。
刷新方式有三种:
①集中刷新:在一个刷新周期中,利用一段固定时间进行刷新,此时间为死时间(死区)。
优点:读/写操作时不受刷新工作的影响。
缺点:集中刷新期间不能访问存储器
②分散刷新:将一个存储器系统工作周期分为两段:前一部分为正常读/写操作,后一部分为刷新。
优点:没有死区。
缺点:加长了系统的存取周期。
③异步刷新:一个刷新周期内每一行仅刷新一次。相邻两行的刷新间隔=刷新周期/行数
注意:
①刷新对于cpu来说是透明的,即刷新不依赖于外部的访问。
②DRAM的刷新单位是行
③刷新操作类似于读操作,但又有不同。(会和cpu有访存冲突)
SDRAM以同步方式交换数据且支持突触发传输方式,DRAM以异步方式交换数据。
行缓冲器用来缓存指定行中整行的数据,其大小为“列数*位平面数”,通常用SRAM实现。
!!!!DRAM芯片的地址引脚复用技术:地址引脚减半
!!!!DRAM芯片行,列数优化:2^n*b位的DRAM存储阵列,行数位r,列数位c,则2^n=r*c。
为了减少地址引脚数,尽量行列数接近,同时,DRAM按行刷新,减少开销人r<=c.
3.2.3 只读存储器ROM
ROM的特点:
①支持随机访问
②结构简单,所以位密度比读/写存储器的高
③具有非易失性,可靠性高
1.掩膜式只读存储器(MROM)
内容由半导体制造厂按用户提出的要求在芯片的生产过程中直接写入,写入后
无法改变其内容。优点是可靠性高,集成度高,价格便宜:缺点是灵活性差、
2.一次可遍程只读存健(PROM)
存储内容由用户用专门的设备(编程器)一次性写入,之后无法修改。
3.可擦除可编理只存储器(EPROM)
修改次数有限,写入时间长,由紫外线擦除(UVEPROM)和电擦除(EEPROM)。
4.FLASH:如U盘,写速度快,但读比写更快,因为写时还要擦除原本数据
5.固态硬盘(SSD)
控制单元+FLASH芯片
- ROM芯片虽然叫做“Read Only”,但是很多ROM也可以写。
- 闪存的写速度一般比读速度慢,因为写入之前需要先擦除。
- 事实上很多ROM也是具有随机存取的特性的,但并不是随机存储器。
3.2.4双端口RAM和多模块存储器
**需要两组完全独立的数据线,地址线, 控制线。**CPU和RAM中也要有更复杂的控制电路。
两个端口对同一主存操作有以下4种情况:
当发生冲突时,会发出忙信号,有判断逻辑决定暂时关闭一个端口(即被延时),未被关闭的端口正常访问,被关闭的端口延长一个很短的时间断后再访问。
其是一种空间并行技术。
(1)多体并行存储器:
图中每个方格表示一个存储单元。
高位交叉编址:每个存储体遍历完了之后再遍历下一个存储体。仅仅相当于扩容。
低位交叉编址:以横向方式遍历存储体,也就是每次都是遍历不同存储体的不同存储单元。这样,在读取其他存储体的存储单元时,之前读取过的存储单元可以利用这段时间进行恢复,达到一种并行的效果。
在模块数的选取上需要保证模块数 m >= T/r,这样才能保证存储体有足够的时间进行恢复。
模块数位m,每个模块由k个单元
第一类问题:地址单元存放位置问题
模块号=单元地址%m
第二类问题:交叉存储器存取时间和带宽的计算
第三类问题:交叉存储器中访存冲突问题
(2)单体多字存储器:
和多体并行存储器相反,单体多字存储器将多个存储体进行了合并,每次只能同时取m个字,不能单独取其中某个字,当某次读写的数据在不同行时,需要读入多余的信息。
双通道内存:
原理:低位交叉编址的多体并行存储器。
3.2.5 主存储器和CPU的连接(重要)
假设有一块 8Kx1位 的存储芯片,说明此芯片需要 13根地址线,CPU有8个数据线和16根地址线,从上面可以看出,CPU每次只能传送1位数据到该芯片中,这会导致CPU的数据线没有得到充分利用,并且会有需要扩展主存容量的情况。
于是,就需要通过多个存储芯片的合理连接来扩展主存容量。
可以有两种方式:
- 位扩展:扩展存储单元的字长
- 字扩展:扩展存储单元的个数
(1)位扩展:
如上图,将两片存储芯片进行连接,CPU地址总线A0~A12会一起发送给这两块芯片,而第二块芯片的数据线D0会和CPU的数据线D1进行相连。这样就扩展成了8Kx2位的存储器了。
同样,CPU中一共有D0~D7个数据线,因此可以总共连接8个图中所示的存储芯片,扩展成 8Kx8位的 存储器。
(2)字扩展:
字扩展可分为两种:
- 线选法
- 片选法
如图中是一块 8Kx8位 的存储芯片,由于该芯片的存储单元字长等于CPU的数据总线数,因此不需要进行位扩展。而地址线并没有被完全利用到,因此可以考虑进行字扩展。
线选法:
用专门的地址线作为片选线,进行选择某一块存储芯片。
如图中:A13为第一块存储芯片的片选线,A14为第二块存储芯片的片选线,当A13 A14分别为01或10时,代表选中了第一块存储芯片或第二块存储芯片,这样就能扩展存储单元的个数。
此时第一块存储芯片的最低地址为:01 0000 0000 0000,最高地址为 01 1111 1111 1111
第二块存储芯片的最低地址为:100 0000 0000 0000,最高地址为 101 1111 1111 1111
但是线选法有一个缺陷:A13和A14不能取00或者11,因为取00时会导致两快存储芯片都没有被选中,11会导致两块存储芯片都被选中。并且需要n个片选信号。
可以进行优化:
只通过A13和一个非门来进行选择。
此时第一块芯片的最低地址为10 0000 0000 0000,最高地址为11 1111 1111 1111
第二块芯片的最低地址为00 0000 0000 0000,最高地址为01 1111 1111 1111
片选法:
相较于线选法就是多了译码器控制。
总结:
(3)位扩展和字扩展 同时扩展
步骤:
1.合理选择芯片
ROM存放系统程序,标准子程序和各类函数。
RAM存放用户编程程序。
2.地址线的选择
芯片容量不同,地址线也不同,通常,cpu的地址线比存储芯片多,大概可以这么存储,低位与地址线相连,高位与扩充存储芯片时使用(视情况而定)
3.数据线的选择
cpu数据线与存储芯片的数据线相等时直连,不等时需要位扩展。
4.读/写命令线的选择
cpu的读/写控制线一般与存储芯片的读/写控制线相连。
5.片选线的选择
3.3外部存储器
结合操作系统来理解!!!!
以磁盘存储介质
优点是:
- ①存储容量大,位价格低
- ②记录介质可重复使用
- ③记录信息可长期保存而不丢失,甚至可脱机存档
- ④非破坏性读出,读出时不需要再生。
缺点:存取速度慢,机械结构复杂,对工作环境要求高。
3.3.1磁盘存储器
1.磁盘设备的组成。
磁盘存储器的组成:磁盘驱动器,磁盘控制器和盘片组成。
①存储区域:一个磁盘含有若干个记录面,每个记录面划分若干条磁道,每条磁道又划分若干个扇区,扇区(也称块)是磁盘读取的最小单位,也就是说磁盘按块读取。
磁头数:即记录面数,表示磁盘共有多少个磁头,磁头用于读取/写入盘片上记录面的信息,一个记录面对应一个磁头
柱面数:表示硬盘上每一个盘每一个盘面有多少个磁道。在一个盘组中,不同记录面的相同编号(位置)的诸磁道构成一个圆柱面。
扇区数:表示每一条磁道上有多少个扇区。
②硬盘存储器:硬盘存储器由磁盘驱动器,磁盘控制器和盘片构成。
磁盘驱动器:核心部件是磁头组件和盘片组件,温切斯特盘是一种可移动头固定磁盘的硬盘存储器
硬盘控制器:是硬盘存储器和主机的接口,主流标准有IDE,SCSI,SATA等。
2.磁盘的性能指标
①磁盘的容量:一个磁盘所能存储的字节总数称为磁盘容量。磁盘容量有非格式化容量和格式化容量之分。
②记录密度:记录密度是指盘片单位面积上记录的二进制的信息量,通常以道密度,位密度和面密度表示。
道密度是沿磁盘半径方向单位长度上的磁道数;位密度是磁道单位长度上能记录的二进制代码位数;面密度是位密度和道密度的乘积。
注意:磁盘所有磁道记录的信息量是相等的!!!
③平均存取时间:平均存取时间=寻道时间(磁头移动到目的磁道)+旋转延迟时间(磁头定位到所在扇区时间)+传输时间(传输数据所花费时间)
④数据传输率:磁盘村暑期在单位时间内向主机传送数据的字节数,称为数据传输率。
假设磁盘转速位r(转/秒),每条磁道容量位N个字节,则数据传输率位D=r*N。
3.磁盘地址
主机向磁盘控制器发送寻址信息,磁盘的地址一般如图所示。
驱动器号:电脑可能有多个硬盘
柱面(磁道)号:移动磁头臂(寻道)
盘面号:激活某个磁头
扇区号:通过旋转将特定扇区划过磁头下方
若系统中有4=22个驱动器,每个驱动器带一个磁盘,每个磁盘256=28个磁道、16=24个盘面,每个盘面划分为16=24个扇区,则每个扇区地址要18位二进制代码,其格式如图所示。
4.硬盘的工作过程
硬盘的主要操作是寻址、读盘、写盘。每个操作都对应一个控制字,硬盘工作时,第一步是取控制字,第二步是执行控制字。
硬盘属于机械式部件,其读写操作是串行的,不可能在同一时刻既读又写,也不可能在同一时刻读两组数据或写两组数据。
5磁盘阵列
RAID(独立余磁盘阵列)是指将多个独立的物理磁盘组成一个独立的逻辑盘,数据在多个物理盘上分割交叉存储、并行访问,具有更好的存储性能、可靠性和安全性。
RAID的分级如下所示。在RAID1~RAID5几种方案中,无论何时有磁盘损坏,都可随时拔出受损的磁盘再插入好的磁盘,而数据不会损坏,提升了系统的可靠性。
RAID0:无冗余和无校验的磁盘阵列。
逻辑上相邻的两个扇区在物理上存到两个磁盘,类比“低位交叉编址的多体存储器”。
RAID0把连续多个数据块交替地存放在不同物理磁盘的扇区中,几个磁盘交叉并行读写,不仅扩大了存储容量,而且提高了磁盘数据存取速度,但RAID0没有容错能力。
RAID1:镜像磁盘阵列。很粗暴,存两份数据。
RAID1是为了提高可靠性,使两个磁盘同时进行读写,互为备份,如果一个磁盘出现故障,可从另一磁盘中读出数据。两个磁盘当一个磁盘使用,意味着容量减少一半。
RAID2:采用纠错的海明码的磁盘阵列。
逻辑上连续的几个bit物理上分散存储在各个盘中;4bit信息位+3bit海明校验位——可纠正一位错
RAID3:位交叉奇偶校验的磁盘阵列。
RAID4:块交叉奇偶校验的磁盘阵列。
RAID5:无独立校验的奇偶校验磁盘阵列。
RAID通过同时使用多个磁盘,提高了传输率;通过在多个磁盘上并行存取来大幅提高存储系统的数据吞吐量;通过镜像功能,提高安全可靠性;通过数据校验,提供容错能力。
3.3.2 固态硬盘
原理:固态硬盘(SSD)是一种基于闪存技术的存储器,属于电可擦除ROM,即EEPROM。
组成:一个SSD由一个或多个闪存芯片和闪存翻译层组成。
闪存芯片:替代传统旋转磁盘中的机械驱动器,每个芯片包含多个块(block),每个块包含多个页(page)。
闪存翻译层:将来自CPU的逻辑块读写请求翻译成对底层物理设备的读写控制信号,负责翻译逻辑块号,找到对应页(Page)。
读写性能特性
- 以页(page)为单位读/写——相当于磁盘的“扇区"
- 以块(block)为单位"擦除",擦干净的块,其中的每页都可以写一次,读无限次
- 支持随机访问,系统给定一个逻辑地址,闪存翻译层可通过电路迅速定位到对应的物理地址
- 读快、写慢。要写的页如果有数据,则不能写入,需要将块内其他页全部复制到一个新的(擦除过的)块中,再写入新的页。
与机械硬盘相比的特点
- SSD读写速度快,随机访问性能高,用电路控制访问位置;机械硬盘通过移动磁臂旋转磁盘控制访问位置,有寻道时间和旋转延迟
- SSD安静无噪音、耐摔抗震、能耗低、造价更贵
- SSD的一个“块"被擦除次数过多(重复写同一个块)可能会坏掉,而机械硬盘的扇区不会因为写的次数太多而坏掉
磨损均衡技术:将“擦除"平均分布在各个块上,以提升使用寿命
- 动态磨损均衡:写入数据时,优先选择累计擦除次数少的新闪存块、
- 静态磨损均衡:SSD监测并自动进行数据分配、迁移,让老旧的闪存块承担以读为主的储存任务,让较新的闪存块承担更多的写任务
3.4Cache(重要)
3.4.1 Cache的基本概念和原理
1.工作原理
将某些主存分块,并将块复制到Cache中,缓和CPU与主存之间的速度矛盾。Cache块也称Cache行,每块由若干个字节组成,块的长度也叫块长。(Cache与CPU之间交互信息的单位是字;Cache与主存交互信息的单位是块,且是根据物理地址访问)
2.局部性原理
- 空间局部性:现在访问的地址,其附近的地址也可能即将被访问。
- 时间局部性:在最近的未来要用到的信息,很可能是现在正在使用的信息。(程序中很可能存在大量的循环结构,需要重复访问)
故Cache能够工作的理论依据:从上面两个局部性可以分析到,我们可以把CPU目前访问的地址周围的部分数据放到Cache中。
注意:时间空间局部性原理的分析
包含代码的时间和空间局部性原理的分析
3.性能分析:
包含Cache命中率和缺失率
包含两种方式
①先访问Cache,再访问主存
②同时访问Cache和主存,若Cache命中则停止访问主存。
注意:
①Cache命中率的计算
设 Tc为访问一次Cache所需时间,Tm为访问一次主存所需时间。
CPU能够直接在Cache中找到所需信息,称为命中。
命中率 H:CPU欲访问的信息已在Cache中的比率。
缺失率(未命中率)M:M = 1 - H
访问CPU平均访问时间 T为:T = H*Tc+ ( 1-H ) ( Tc+Tm )
例题:
②Cache命中对于CPU执行时间的影响
当CPU发出读请求时:
第一种情况:访存地址在Cache中,则命中,将此地址改为Cache地址,直接读Cache。
第二种情况:访问地址不在Cache中,需要访问主存,并一次性将主存的地址调入Cache中。
若Cache满,则需要使用替换算法。整个过程全部由硬件实现,且CPU与Cache之间交换数据以字为单位,CPU与主存交换数据以Cache块为单位。
当CPU发出写请求时:
Cache命中,可能出现Cache与主存内容不一致问题,需要用到对应的写策略。
③Cache行长和Cache容量之间的区别
Cache行长一般指Cache行中的数据部分的长度,即实际存储的主存数据块内容的长度。这个长度通常是固定的,并且由Cache的设计决定。
Cache的总容量不仅包括存储的数据部分,还包括用于管理Cache的其他控制位,如标记(Tag)、有效位(Valid Bit)、脏位(Dirty Bit)等。
Cache的总容量计算公式可以表示为:Cache的总容量 = 行数 × (数据部分长度 + 控制位长度)。其中,数据部分长度是Cache行长,而控制位长度则取决于Cache的设计和实现,包括标记长度、有效位、脏位等。
Cache行所有内容:
有效位 | 脏位 | 替换位 | tag | 数据项 |
!!!!!讨论Cache组织结构时不直接考虑控制位,但在计算Cache的实际总容量时,我们必须将这些控制位考虑在内
Cache和主存之间仍然存在一些问题:
- 如何区分Cache和主存之间的数据块对应关系? ——Cache和主存的映射方式
- Cache很小,主存很大。如果Cache满了怎么办? ——替换算法
- CPU修改了Cache中的数据副本,如何确保主存中数据母本的一致性? ——Cache写策略
总结:
3.4.2 Cache和主存的映射方式
主存地址结构 :
主存块号 | 块内地址 |
上述是普遍情况,根据三种不同映射方式,会将主存块号分成几个部分,见下。
分为三种映射方式,全相联映射,直接映射,组相联映射。
1.全相联映射
任何一个主存块可以放在Cache的任意位置。
给每一个Cache块增加一个标记位,记录对应的主存块号。
还需要一个有效位,有效位为1时表示标记位有效,有效位为0时表示标记位无效。
以上图为例,主存中任意一块数据都可以存放在Cache任意一块中,只要标记好和主存数据的对应就行。例如主存中第9号块数据可以存放在Cache中0号到1号任意一个位置。
优点:Cache存储空间利用充分,命中率高。
缺点:查找速度较慢。
故CPU访问主存数据的流程如下:
地址结构:
- 主存地址 = 主存块标记(地址) + 块内地址
- Cache地址 = 标记+ 块内地址
标记(主存块号) | 块内地址 |
注意:根据地址结构和比较器数量来判断映射方式
每个Cache行都设置一个比较器,比较器位数等于标记字段位。查找过程是按内容访问的存取方式。
比较器的作用:确定从主存中请求的数据是否已经存在于缓存中。(有效位)
2.直接映射
每个主存块只能放到特定的一个位置:Cache块号 = 主存块号 % Cache总块数。
以上图为例,8块为一个循环。主存中0号和8号块数据可以存放在Cache第0号块中,主存中1号和9号块数据可以存放在Cache第1号块中,以此类推。
若Cache总块数 = 2n,则主存块号末尾 n 位直接反映它在Cache中的位置。这是因为Cache块号 = 主存块号 % Cache总块数 = 主存块号末尾 n 位。
于是对于Cache所保存的标记号可以不用保存主存中对应的整个地址,可以只保留主存块号m前面(m-n)个二进制数。
这里Cache行长为64B。
故CPU访问主存数据流程如下:
优点:只需要对比一个标记,速度最快。
缺点:Cache存储空间不充分,命中率低。
注意:
①直接映射地址结构以及映射关系分析
地址结构:
- 主存地址 = 主存块标记(区地址) + Cache行号(索引)+ 块内地址
- Cache地址 =标记+ 块内地址
主存块标记位数=主存容量/Cache容量 其实就是相当于主存分了多少个区也可以是
主存地址总位数-块内地址位数-行号位数
Cache行号位数=Cache容量/Cache大小
块内地址=Cache行大小所需存放的位数
主存字块标记 | Cache行号 | 块内地址 |
上述三个一起组成了主存地址,后两个组成Cache地址。
3.组相联映射
将Cache块分为若干组,每个主存块可放到特定分组中的任意一个位置。全相联映射和直接映射的结合体。
每个主存块对应的组号 = 主存块号 % 分组数
以上图为例,8块为一个循环组。0号和8号同属于第0组,0号和8号数据可以存放在第0组的任意一个位置,只要做好标记就行。
和直接映射一样,若Cache总分组数 = 2n,则主存块号末尾 n 位直接反映它在Cache中是第几组。
故CPU访问主存数据流程如下:
假设以下采用2路组相联映射,也就是 2块为一组,分四组。
优点:上面两种方法的折中,综合效果较好。
地址结构:
- 主存地址 = 主存块标记(区号标记) + 组地址(索引)+ 块内地址
- Cache地址 =标记+ 块内地址
标记 | Cache组号 | 块内地址 |
注意:
①组相联映射的访存过程以及Cache缺失处理
②组相联映射中比较器的个数和位数
直接映射应为每块只能映射到唯一的Cache行,因此只需要1个比较器。而r路组相联映射需要在对应分组中与r个Cache行进行比较,因此需要设置r个比较器。
③直接映射,组相联映射相关标记位以及总容量的分析
④组相连映射相关标记位的分析
每个Cache行对应一个标记项【包含有效位(数据是否有效),脏位(判断是否进行过修改),替换算法位(使用的替换算法是什么),标记位】
有效位 | 脏位 | 替换控制位 | 标记位 |
总结:
关于Cache和主存映射还有什么不理解的地方可以去看这个博客,我觉得讲的很好:
https://blog.csdn.net/weixin_46371813/article/details/107631076?ops_request_misc=&request_id=&biz_id=102&utm_term=cache%E5%92%8C%E4%B8%BB%E5%AD%98%E7%9A%84%E6%98%A0%E5%B0%84&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-0-107631076.142^v100^pc_search_result_base9&spm=1018.2226.3001.4187
3.4.3 Cache替换算法
直接映射方式 由于主存数据块对应的Cache块是固定的,所以没得选择,不需要使用替换算法。
而全相联映射和组相联映射方式 由于可以选择不同位置进行替换,所以需要用到替换算法进行替换。
下面例子以全相联映射方式进行举例。
1.随机算法(RAND)
若Cache已满,则随机选择一块替换。
举例:
图中红色表示该位置被重新替换成新的块。
图中绿色表示命中该缓存块。
- 随即算法实现简单,但完全没考虑局部性原理(时间局部性),命中率低,实际效果很不稳定。
2.先进先出算法(FIFO)
- 若Cache已满,则替换最先被调入Cache的块。
举例:
从上图可以看到,红色出现很多次,这表明缓存块被频繁地替换,刚被替换的块很快又被重新调入,这称为抖动现象。
- 先进先出算法实现简单,但是依然没考虑局部性原理(时间局部性),因为最先被调入Cache的块也可能是被频繁访问的。
3.近期最少使用(LRU,least recentl use)
手算直接从当前往前。
- 为每一个Cache块设置一个”计数器“,用于记录每个Cache块已经多久没被访问过了。当Cache满了之后替换”计数器“最大的。
- 计数规则:
- 命中时,所命中的行的计数器清零,比其低的计时器加1,其余不变(加一没有意义)。
- 未命中且还有空闲行时,新装入的行的计数器置0,其余非空闲行全加1。
- 未命中且没有空闲行时,计数值最大的行的信息块被淘汰,新装行的块的计数器置0,其余全加1。
举例:
一开始,缓存块中并没有存储数据,计数器均为0。
访问主存块1
访问主存块2
访问主存块3
访问主存块4
访问主存块1,命中缓存,Cache0计数器重新清零
访问主存块2,命中,Cache1计数器重新清零
访问主存块5,此时未命中,将会采取下先进先出算法,替换计数值最大的块,图中替换Cache2
接下来的流程和上面类似,只需要根据计数规则自行模拟即可,这里不再赘述。
- 近期最少使用算法 基于 局部性原理,近期被访问过的主存块,在接下来的时间内很可能还会被访问,因此淘汰最久没被访问过的块是合理的,该算法实际运行效果优秀,Cache命中率很高。
- 若被频繁访问的主存块的数量 > Cache行的数量,则还是有可能发生抖动。
注意:①LRU依据程序访问的局部性原理,平均命中率较高,是堆栈类算法。
②LRU替换位以及其位数的计算:设置了计数器过程见上。
4.最近不经常使用(LFU)
手算直接从当前往前推。
-
为每一个Cache块设置一个”计数器“,用于记录每个Cache块被访问过几次。当Cache满后替换“计数值”最小的。
-
新调入的块计数器=0,之后每被访问过一次计数器+1。
举例:
访问了主存块1号,2号,3号,4号后,Cache的状态:
访问主存块1号和2号时均命中,Cache0和Cache1计数器加一。当访问主存块5号时,未命中,于是会替换计数值最小的Cache2(这里Cache2和Cache3均为0,会按行号递增或者FIFO策略来进行选择哪一个被替换)
接下来的流程和上面类似,根据 最不经常使用算法 自行模拟即可,这里不再赘述。
- 评价:曾经被经常访问的内存块在未来并不一定仍然被访问,并没有很好地遵循局部性原理(时间局部性原理),因此实际效果并不如 近期最少使用算法 LRU。
总结:
3.4.4 Cache写策略
为何不讨论读命中,读不命中的情况?
因为读不会导致主存和Cache的数据不一致。
1.写命中
(1)回写法:
-
当CPU对Cache写命中时,只修改Cache的内容,而不立即写入主存,只有当此Cache块被替换时才写回主存。
-
需要增加一位脏位(修改位),用于标记该Cache块是否被修改了。
-
减少了访存的次数,但存在数据不一致的隐患。
(2)全写法:
- 当CPU对Cache块写命中时,必须把数据同时写入Cache和主存中,一般使用写缓冲(write buffer)。
- 访存次数增加,速度变慢,但能保证数据的一致性。
- 使用写缓冲,CPU写的速度很快,若写操作不频繁,则效果很好,若写操作很频繁,可能会因为写缓冲饱和而发生阻塞。
2.写不命中
(1)写分配法:
- 当CPU对Cache写不命中时,把主存中的块调入Cache中,在Cache中修改,通常搭配回写法使用。也就是发生替换时才写回主存。
(2)非写分配法:
- 当CPU对Cache写不命中时,只写入主存,不调入Cache中。搭配全写法使用。
3.多级Cache
现代计算机常采用多级Cache:
-
离CPU越近的速度越快,容量越小
-
离CPU越远的速度越慢,容量越大。
各级Cache之间常采用 全写法 + 非写分配法。
Cache 和 主存 之间常采用 写回法 + 写分配法。
总结:
3.5 虚拟存储系统
虚拟存储器中数据调动(如地址映射)由硬件和操作系统共同完成。
3.5.1 页式存储
有时候一个程序比较大,无法将它顺序地存放在主存中的各个块中,因此操作系统会将它分成若干个页面,页面的大小和块的大小相同,每个页面以离散地放入不同的主存块中。
逻辑地址(虚地址):程序员看到的地址。
物理地址(实地址):实际在主存中的地址。
对于一条机器指令:000001 001000000011(操作码+地址码),其地址码所使用的就是 逻辑地址。
页表:记录了每个逻辑页面存放在哪个主存块中,页表的数据放在主存中。
地址变换过程:举例
假设此时执行一条取指令操作,该指令为 000001 001000000011,所以要取的数据的逻辑地址为 001000000011
- 首先将逻辑地址拆分成 逻辑页号 和 页内地址。
- 在主存中找到 页表,然后通过 逻辑页号 进行查表,查出对应的 主存块号。
- 将 主存块号 拼接 页内地址 得到最终的 物理地址。
- 到Cache中查找该物理地址,找不到的话再到主存找。
但是由于页表是存放在主存中的,而根据时间局部性原理,刚使用的数据很可能在接下来还会使用,这样在下一次使用该数据时又得访问一次主存进行查表,为了更快地查表,会将近期访问的页表项放入更高速的存储器中,称为 快表。
快表:快表是一种相联存储器,可以按照内容进行寻访,并且其采用的是SRAM,访问速度更快。
快表 和 Cache 的区别:
- 快表 存储的是 页表项的副本
- cache 存储的是 主存块的副本
总结:
3.5.2 虚拟存储器
虚拟存储系统:辅存中的数据并不是一次性全部加载到主存中的,而是和 Cache——主存 类似,根据局部性原理加载一部分数据到主存中。
举例:打游戏时的“Loading”界面背后可能就是在 将游戏地图相关数据调入内存中。
注意:虚拟存储器只能使用回写法。
原因:虚拟存储器采用类似于Cache的技术,将辅存中常用的数据副本存入主存中。同时因为缺页(缺段)而访问辅存的代价大,提高命中率是关键,因此虚拟存储机制采用全相联映射,每个需页面可以存放到对应主存区域的任何一个空闲页位置。此外,当进行写操作时,不能每次写操作都写回磁盘,因此处理一致性问题时,采用回写法。
1.页式虚拟存储器
和Cache、主存类似,辅存中数据也被分为一个一个的块。
主存空间的页叫做物理页,实页,页框,虚拟地址空间中的页叫做虚拟页,虚页。
与主存交换的单位是页。
为了实现只加载一部分数据到主存中,需要对页表补充一些信息。
-
逻辑页号:逻辑地址中的页号
-
主存块号:物理地址中的主存块号
-
外存块号:辅存中对应的块号
-
有效位:这个页面是否被调入主存中
-
引用位(访问位):用于页面替换算法,主存也有用完的时候,需要进行替换,例如可以使用最不经常使用算法,统计访问次数。
-
脏位(修改位):这个页面是否被修改过,修改主存后会导致主存和辅存之间数据不一致。
优点:页面长度固定,页表简单,调入方便。
缺点:程序不是页面的整数倍时会有浪费
快表(TLB) :类似于Cache作用,利用程序局部性原理,将一段时间内经常访问的数据存放在相联存储器组成的快表中。
主存中的页表也叫慢表(Page)。
注意:TLB,Cache,Page缺失的综合分析
Page缺失,TLB必然缺失。Page缺失,Cache也必然缺失。
下面时三个表缺失可能组合:
序号 | TLB | Page | Cache | 说明 |
1 | 命中 | 命中 | 命中 | TLB命中则Page一定命中,信息在主存,就可能在Cache层 |
2 | 命中 | 命中 | 缺失 | TLB命中则Page一定命中,信息在主存,也可能不在Cache中 |
3 | 缺失 | 命中 | 命中 | TLB缺失但Page可能命中,信息在主存,就可能在Cache层 |
4 | 缺失 | 命中 | 缺失 | TLB缺失但Page可能命中,信息在主存,也可能不在Cache层 |
5 | 缺失 | 缺失 | 缺失 | TLB缺失但Page也可能缺失,信息不在主存,也不一定在Cache层 |
由于主存和辅存之间的数据调入是由操作系统来调控的,因此具体细节请看操作系统相关内容,以上仅做粗略介绍。
- 主存——辅存:实现虚拟存储系统,解决了主存容量不足的问题。
- Cache——主存:解决了主存和CPU之间速度不匹配的问题。
注意:①数组的分页存放,缺页异常分析以及缺页处理过程。
缺页是CPU在执行指令的过程中进行取指令或读/写数据的一次故障,属于内部异常。
②虚拟地址结构分析:
虚拟存储系统中,指令给出的地址时虚拟地址,因此当CPU执行指令时,要先将主存虚拟地址转化为主存物理地址。虚拟地址分两段,高位为虚页号,低位为页内偏移地址。物理地址也是两个字段,高位为物理页号,低位为页内偏移地址。
2.段式虚拟存储器
按照功能模块进行拆分,把虚拟地址分为两部分:段号和段内地址。段表每行记录与某个段对应的段号,装入位,段起点,段长等信息。
分段程序对于程序员来说是不透明的,而分页程序对程序员来说是透明的。
段式虚拟存储器的优点:段的分界与程序的自然分界相对应,因而具有逻辑独立性,使得其易于编译,管理,修改,保存。
缺点:段长可变,分配空间不便,容易有碎片,不好利用,浪费。
例如:#0段是自己的代码,#1段是库函数的代码,#2段是变量。
和页式存储类似,操作系统以段为单位来决定哪一些段应该被调入内存中。
3.段页式虚拟存储器
把程序先按功能模块分段,每段再划分为固定大小的页,主存空间也划分为大小相等的页。
程序对主存的调入,调出仍然以页为基本传送单位,每个程序对应一个段表,每段对应一个页表。
虚拟地址:段号 + 段内页号 + 页内地址。
优点:兼具页式和段式虚拟存储器的优点,可以按段实现共享和保护。
缺点:地址变换过程中要查两次表,系统开销大。
具体详情请看操作系统内容。
3.5.3虚拟存储器与Cache比较
相同:
- 最终目标都是为了提高系统性能,两者都有容量,速度和价格的梯度
- 都把数据分为小信息块,并作为基本交换单位,虚拟系统的信息块更大
- 都有地址映射,替换算法,更新策略等问题
- 都依据局部性原理应用快速存储的思想,将活跃的数据放在相对告诉的部件中。
不同:
- Cache主要解决系统速度,而虚拟存储器却是为了解决主存容量。
- Cache全由硬件实现,是硬件存储器,对所有程序员透明;而虚拟存储器是由OS和硬件共同实现,是逻辑上的存储器,对系统程序员不透明,但对应用程序员透明。