目前正在备考24考研,现将24计算机408学习整理的知识点进行汇总整理。
博主博客文章目录索引:博客目录索引(持续更新)
寄存器包含ACC、MQ等,速度要比cache快得多。
此时由于这种关系,应用程序员所看到的主存通常较大,下面是主存-辅存、Cache-主存解决的问题:
各层存储器的速度与价格:光盘->机械硬盘->固态硬盘->内存条
①半导体存储器:如主存、Cache
②磁表面存储器:软盘、磁带、机械硬盘(下图从左到右)
③光存储器:光盘、DVD、VCD都是光存储器
①随机存储器,如内存条:访问指定地址的时间都是一样的
②顺序存取存储器:复读机中放的磁带
若是需要读取磁盘中的某一块内容,则需要等待磁头转到那边
③直接存取存储器
例如机械硬盘、磁盘都是典型的直接存取存储器,既有随机存取的特性,又有顺序存取特性。
首先磁头臂会进行前后的移动到想要读取的区域,接下来会有个磁盘,不断滑动,这个磁盘就可以相应的读和写。
存取速度(小到快):顺序存储存储器->直接存取存储器->随机存取存储器。
④相联存储器:根据根据要找的内容,直接去寻找内容对应在哪里。
不同:①-③根据地址访问、④根据内存访问。
①存储容量:存储字数x字长
(如1M x 8位)
②单位成本:每位价格=总成本/总成本
,每个bit位付出的金钱成本。
举例:
③存储速度:数据传输率=数据的宽度/存储周期
,数据的宽度即存储字长
主存储器分为存储体、MAR(地址寄存器)、MDR(数据寄存器)三个部分:
这三个部分会在时序控制逻辑电路中相互配合使用:
基于上面的存储元来介绍下读出、写入原理:
**如何读取多个存储二进制值呢?**通过去读取存储单元来进行,如下,由多个存储元组成的一个存储单元,在存储单元上每个MOS管接线,若是想要读取一组单元的存储元值,直接全部上电压,就能够读取到一个存储单元的所有二进制位(每个存储元中的电容)。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hoJqQwm8-1686883020451)(C:\Users\93997\AppData\Roaming\Typora\typora-user-images\image-20230529171556838.png)]
如何根据地址来决定我们要读或者写哪个存储字呢?
计算下总容量:三位的话就有8条线。
控制电路作用:①对于传输数据到MAR当中时可能并不稳定,所以控制电路做的一个工作就是,只有当MAR当中的数据稳定之后才会去打开译码器开关来进行读取并翻译地址来给出信号。②于此同时传输到MDR的数据也要稳定了之后才能够传输给数据总线,这也是由控制电路控制的。
自带有两个片选信号:
额外有两跟读/写控制线,由两种设计方案:①读写各单独一根。②读写一根线,根据输入的高低电平来确定是什么操作。
注意:通常题目中会告知你使用几根读/写线。
完整的一个存储器芯片如下:
此时对整块存储器芯片来进行封装:
片选线的作用?
**对应每个存储芯片下都有如下图一样的金属引脚这是什么呢?**这个是就是我们上图封装好之后对应的地址线、数据线、片选线以及读/写控制线相对应的引脚,用于其他模块来传入进来数据。
关于寻址的问题主要来看存储器中的存储矩阵,数据是存储在这里:寻址方式可按照字节、字、半字、双字来进行寻址,不同寻址对应的编号也不同,若是更大是倍数,存储单元个数可进行右移
DRAM
在2.1节当中学习的就是DRAM芯片,采用的是电容存储的,对于SRAM则是采用的双稳态触发器来存储信息:
SRAM
双稳态触发器的读/写原理:
其中双稳态触发器有6个,在这种存储器中可以呈现出两种稳定的状态:
对于左边电容存储元读出数据的数据线只有一根,右边双稳态触发器则需要两根来读取数据,我们可以根据BL或者BLX读出的是0或1就能够确定读出的是什么信号了。
如何写入数据呢?
两者的区别:
一方面:存储元件上导致的区别,也就是读数据是否需要重写的情况,DRAM在读数据后需要有一个重写操作,而SRAM无需重写。
另一方面:
对于DRAM需要2ms刷新一次,若是不刷新原本电容中的数据就会丢失!
针对于DRAM刷新来进行详细介绍:
简单模型:
行列地址模型:
将一个译码器分为两个也就是行列译码器,那么此时一个译码器负责210,总共也只需要执行210次,此时只需要一千次,大大提升效率,分为拆为n/2:
随着存储器发展,存储容量越来越大,现在一些存储器还有三维的排列,原理类似。
示例:给你一个地址00000000如何来进行访问。
第一种方案:选通的是0号存储单元
总共需要28也就是256根选通线:
第二种方案:各自拆成一般分别送到行地址译码器以及列地址译码器
针对于行列地址译码器只需要32根:
有多种刷新思路如下:
①分散刷新:这种思路针在一个2ms周期中可以进行2000次刷新,是能够满足128x128中的128次的。
②集中刷新:集中一段时间进行读写,然后再集中一段时间去刷新,在这一段刷新时间中无法访问存储器
③异步刷新:在这个过程中将死时间进行了分散,可以利用CPU不需要访问存储器的时间段(例如利用CPU在译码的时间段)来进行刷新
同时送:一个地址前面部分送到行地址译码器,而地址后一半部分送到列地址译码器当中,此时需要同时传输行与列地址,也就是需要n位地址线来进行同时传输
在DRAM中通常采用地址线复用技术:也就是行地址与列地址通过前后两次分别进行传输,使用n/2根地址线,通过增加一个行地址缓冲器以及一个列地址缓冲器,分开传输
通过这种策略,原本n条地址线此时就可以优化为n/2根。
ROM的发展史如下: 基于上图的五个
①MROM:只能读而不能写的存储器。
初始化是厂家完成的,可根据需求来将指定数据写入,采用的是一种掩膜技术,对于掩膜技术只能够进行批量定制。
②为了提高只读存储器的灵活性,此时就发明了PROM。用户可以使用专门的PROM写入器来写入信息,写一次后就无法更改。
③接着又出现了EPROM,可以允许多次重写。可以通过一些特殊的手段往里面写数据。
针对于EPROM分为下面两个类型:
④此时又出现了Flash Memery(闪存),保留了EEPROM的优点断电后可以保存信息,还可进行多次的快速擦除重写。
注意点:闪存需要先擦除再写入,写速度比读速度更慢。
⑤接着随着技术发展,又出现SSD(固态硬盘),也是由闪存芯片来存储二进制数据的,其中多了一个控制单元,用来控制多块闪存芯片的读和写。
实际上许多固态硬盘、U盘的介质都是闪存芯片,与U盘的区别在于控制单元不一样。
CPU在刚开始执行的一段程序,需要从BIOS中读取指令:
实际上对于主存同样包含ROM,是由RAM+ROM组成,二者统一进行编址,如下:
以前的存储芯片中集成着MDR与MAR,如今在计算机中这两个元件是集成在CPU当中:
目前主存中包含多块存储芯片见如下:
WE:表示写使能信号,write Enable,若是高电平表示写数据,低电平表示读数据。CPU也有对应的WE线来进行发送信号,通过控制信号发送过去。
CS:片选信号,由于只有一块芯片工作,可以直接接上高电平信号,因为CS头上没有划横线,表示片选信号高电平有效。
来看整体的连接情况,可以发现数据总线仅仅只连接了一位,地址总线也只连接了一部分,并没有充分发挥CPU的性能,解决这样的问题可以给主存再加上一块相同型号的芯片
位扩展:此时我们总共有两块主存储器,总体来看数据读取位长有两位,此时可以同时读与同时写两位
新连接一块存储芯片,可以将新的D0连接到CPU的D1,对应的A地址线与第一块连接一致即可读取时可以都传入到各自的地址线当中。
完成8位数据线扩展如下,我们需要增加8个8K x 1位的即可完成扩展:
主要包含两种选法:
线选法:CPU上的n根线对应n个存储芯片。
译码片选法:CPU上的n根线对应2n个存储芯片,利用率更好。
线选法
使用CPU的两个地址线来进行举例:
A13与A14一个为0,另一个为1时的最低地址与最高地址:分别各自表示
A13与A14都是1则会造成冲突情况:可以看到底部出现了冲突
若是都是0,由于CS表示的时高电平有效,此时两个存储芯片都不会选。
译码片选法
译码片选法:通过使用一个译码器来实现转换,1个地址线可转2个,2个地址线可转4个,也就是2n
此时我们只使用一个A13来对应一个译码器,当A13为1时:通过译码器转换后,对于第一个存储芯片传输的为低电平那么第一个不选用,第二个存储芯片传输的则是1也就是高电平,此时第二个存储芯片生效
当A13为0时,此时第一个存储芯片生效:
地址范围为:
可以看到上面的A13仅仅只是选择一个转2个,那么对应这个译码器就是1-2译码器:可有0xxxx、1xxxx对应两个存储芯片
3-8译码器:输入信号为000、001、010、011、100、101、110、111,可接8个存储芯片
下面给出一个扩展4个存储芯片示例:在下面的存储芯片CS上有一个横线,表示低电平有效,此时你也可以看到对应的译码器上有一个圈表示是非的含义,也就是当这个线传输到CS横时为0才有效:
字位同时扩展示例:
CPU是64位地址线,数据宽度为8位,对应的存储芯片是16k x 4位,那么此时我们需要4块存储芯片来进行字扩展,同时2个存储芯片需要进行位扩展,由于字位同时扩展,所以需要2*4=8块,可以看到上图的左边红框可以组成一个16k x 8位,那么需要4个来进行子扩展,则能够实现了主存容量扩展。
可以看到下图的左右两边是两种不同的生效情况,左边是高电平有效、右边是低电平有效:
对应译码器中还包含使能信号:左边的是单个的,右边则有多个使能
介绍CPU->译码器->存储芯片的过程:CPU首先会通过地址线送出地址信号,包括更低的13位与更高的3位,地址信息是通过电信号来输出的,当CPU刚开始输出电信号的时候,电信号有可能不稳定,因此CPU送出这些地址信息之后,需要等一下,等电流稳定之后再发出主存请求信号(MREQ),也就是让选通线的一个信号有效,当一块存储芯片选通之后,这块存储芯片所接收到的信号一定是稳定的。
RAM读周期详解:
位扩展:使存储器的字长变得更长,从而更能发挥数据总线的传输能力。
字扩展:可以增加存储器的存储字数,可以更好的利用CPU的寻址能力。
可以在不同的维度扩展发挥数据总线的传输能力,增加存储器的存储字数更好的利用CPU的寻址能力。
存取周期如下:
对于DRAM芯片读请求是破坏性请求,读取之后需要进行恢复,上图中存取时间就是DRAM读取一个字的时间,读完之后则需要一段恢复时间,在这个恢复时间中CPU无法访问。
此时针对于存储芯片读取一个字时需要等待恢复时间这种情况来提出问题并进行解决:
1、多核CPU中一个CPU访问了一块内存之后需要恢复时间,那么由于是多核,此时另一个CPU在之前CPU的等待恢复时间也要访问该块空间,如何解决?
2、单核CPU读写速度比主存快很多,对于主存恢复时间过长如何解决?
双端口RAM如下进行设计:
介绍:可以看到上图中的一个RAM左右两边都可以去联通CPU,若是要支持这种多CPU的访问模式,我们需要在一个RAM存储器中有两组完全独立的数据线、地址线、控制线,于此同时RAM中也需要更多更复杂的控制电路。
好处:对于这种设计方式可以优化多核CPU访问一根内存条的速度。
多个端口对同一主存允许操作:不同端口对不同地址单元存取数据;不同端口对同一端口可读取数据;
解决不允许的操作方案:采用双端口时会出现四种情况,对于写写、读写操作应该禁止,这个禁止是通过电路来进行实现的。
针对于单CPU多次访问主存等待恢复时间过长问题,我们可以采用多体并行存储器来进行解决,也就是将一块存储器来拆为多块可供CPU访问,可分为高位以及低位交叉编址:
对于高位与低位交叉编址的区别是什么呢?每个地址是根据体号与体内地址组成,对于高位交叉编址是体号在前,体内地址在后;对于低位交叉编制是体内地址在前,体号在后。
对于不同的地址设计,对应的地址编号顺序也会受到影响各不相同,我们可以发现高位交叉编址的内存地址顺序依次是从第一根从上至下,接着第二个往下,而对于低位交叉编址则是一个一个地址分离对应的多块相隔,对于这样的区别有什么影响呢?
下面举一个例子:访问连续的5块地址,我们分别来看采用高位交叉编址与低位交叉编址的读取时间
①高位交叉编址
由于连续的5个地址都是在分为四根的第一根存储器中,那么相当于会连续访问5次同一根,每次访问的时间都包含了存取时间1r以及等待时间3r:
可以看到每访问一次实际需要4r,也就是1T,第二次由于访问的也是同一根需要等待时间结束后才能够访问,之后的几次同样如此,总共需要时间为5T。
②低位交叉编址
采用低位交叉编址地址编号是一根隔着一根的,所以访问第一位时是在第一根,此时需要使用读取时间1r,在1r之后可以直接读取第二根,无需进行等待,后面3、4根同样如此,由于我们上面低位交叉编址是设置了4根,所以我们在第五次访问位的时候会访问第一根,此时可以发现,正好3r的等待时间已经结束,此时同样无需等待可直接进行访问。
采用这种方式可以十分高效速度去读取,耗时只需要T + 4r,也就是2T!
小总结:当访问一根内存条的存储器时,每次访问都必须有等待时间,对于同样顺序读地址时
从效率上来看,低位比高位高出很多足足有4倍。
程序指令的执行是顺着一条一条往下执行的,一般就是连续存储,除非碰到if else情况。
上述可以看出低位交叉编址的多体存储器针对于连续地址访问效率十分高,那么具体应该取几个体呢?
下面给出不同模块数的情况:
总结表述:
①直接根据末尾的体号来判断。②根据给定的m,来让x % m进行取余处理。
前者可以任意去读取某个存储器中的字,后者每次只能去读取一行,有时候读取跨行的几个字会导致多读数据。
速度对比:前者每读取一个字接近r,读取四个就是4r;后者每次读取一行,读取一行需要1T,也是4r,所以读取速度差不多。
我们在日常生活中所说的扩容以及双通道实际上就是我们上述所介绍的高位交叉以及低位交叉情况,采用低位交叉可以构成双通道,此时读取速度可以大大提升!
如何构成双通道?一条16GB的可以换成两条8GB的,分别插入到上面相同颜色卡槽中,此时就可以构成双通道。
那么我们为什么要挑选相同主频以及相同容量的呢?
实战:对于电脑中的双通道我们也可以在系统里查看,例如下面的两条8GB,分别在0、2号插槽,那么也就是出厂的时候就是配置的双通道。
计组:主要考察硬件特性;操作系统:考察对磁盘的管理,调度算法。
对于主机传来的8bit数据我们需要搞一个电路将其8bit数据搞成串行的方式1bit、1bit的进行写入,读取数据也同样如此。
磁盘读取二进制比特位的原理:磁带划过磁头下方时,磁头就可以1bit、1bit的往里面写数据,每次只能写1bit;读数据同样如此,可以通过读线圈1bit、1bit的读数据。
特性:①磁盘每次读或写都是1bit、1bit进行操作的。②读与写操作是不能够一起进行的。
认识磁盘存储器:
①存储区域
磁头:每个盘面都有一个读写磁头(一个磁盘存储器可能有多个盘面)。
磁道:每个盘面一圈一圈的就是磁道,由于磁盘内部有多个盘片,每个盘片划分多个磁道。
柱面:不同盘片相同编号位置磁道构成一个柱面。
扇区:每个盘面可以划分多个扇区
主机每次对磁盘读和写都是以扇区为单位。
②硬盘存储器
需要磁盘驱动器、磁盘控制器(IO控制器)、盘片
可以注意到:对于磁头有上下实际上可以读取上与下的盘片,最顶部与最底部没有。
①磁盘容量
容量:
格式化容量比非格式化容量要小。
②记录密度
磁盘上扇区从外到里每一圈存储的bit位数都相同,只是密度不同,越靠内侧密度越低。
③平均存取时间
寻道时间+旋转时间+传输时间(让磁头划过整个区域完成读写)
整个存取时间过程图示:
磁盘控制器延迟:给磁盘发出读写命令也需要花费一些时间。
④数据传输率
根据磁盘地址来进行编号:
磁盘的工作过程:寻址、读盘、写盘,都是通过控制字来进行发出的。
读取过程需要借助一个串-并变换电路:
磁盘阵列主要目的:提升系统性能以及磁盘存储的可靠性。
磁盘冗余阵列:将逻辑上相邻的数据实际放置在不同层面中,此时就能够进行并行的访问。
RAID0:若是有一些扇区坏了的话无法恢复数据。没有容错能力。
可通过软件的处理,将原本逻辑盘连续的磁盘去管理为四个物理盘,此时可以使整个磁盘系统读写速度更快。
出现的问题:
RAID1:镜像磁盘阵列
方案:可以采用更安全的磁盘阵列。每个物理磁盘上都存放一份数据,此时有冗余但有校验的功能,相对的代价则是存储空间浪费一半。1:1
RAID2:提高磁盘进一步利用率,逻辑上相邻的几个bit分散存储在四个物理磁盘中,同时增加几个磁盘用来保存4bit对应的3bit海明校验码就可以纠正一位错并恢复。4:3
RAID3-5:其他策略。越往后可靠性越高越安全。
为了增加可靠性与并行访问能力,商用级别经常使用这种磁盘冗余阵列提升磁盘系统性能与可靠性。
小总结如下:
2023年出现选择题概率十分高。
机械硬盘存储数据都是基于小盘面上的磁性物质来记录二进制0与1;固态硬盘存储介质基于闪存技术(u盘同样也是)。
通过IO总线来发送逻辑地址,接着通过闪存翻译层来映射到对应的物理地址,闪存翻译层做的是地址变换的工作。
接着深挖闪存芯片内部的结构,一个闪存芯片由若干个数据块组成,一个块大小在16KB-512KB。
每一个块可以拆解为一个个页,每个页大小为512B-4KB。
注意:系统对于固态硬盘的读写是以页为单位的。每次读/写一个页。
针对其中一个特性:固态硬盘会以块的单位擦除,擦干净的块,其中的每页都可以写一次,读无限次。
若是在一个块中先写了几个页,那么再去修改那几个页是不被允许的,除非去把整一块擦除才能够重新写。
若是我只想重写一页呢,难道要把整一块来进行擦除吗?实际上固态硬盘会将指定的除了那一页的其他页写入到其他块中也就是先复制到另一块中,然后将新的一页页写到另一块中,接着将原先的那一块擦除即可。
由于这个特性导致固态硬盘读快,写慢
关于机械硬盘与固态硬盘定位的区别:固态硬盘是通过电路迅速定位;机械硬盘则通过移动磁臂旋转。
固态硬盘的缺点:若是频繁的在一个块上进行擦写重写,那么会导致坏掉。
根据这个缺点,就有了解决方案:磨损均衡技术。也就是想办法将擦除平均的分布在各个块上,用于提升使用寿命。针对于读多写少的数据块则可以将其数据迁移到比较老的块上。主要原因是读多写少,那么对于擦除的需求就很少。
大题和小题的高频考点
存储系统存在的问题:优化后速度与CPU差距依旧很大,可以增加一个cache层来进行缓和。
cache的工作原理:在一小段时间内,会有同样的一段代码或者数据被频繁的访问与使用,此时我们可以将其读入到cache中。
空间局部性(与目前使用比较靠近的)、时间局部性(最近未来要使用的,很可能是现在要使用的)
举例:例如访问二维数组,若是跳着去访问隔行的空间局部性更差,若是依次是一行中的元素,那么空间局部性更好。
性能分析:H表示CPU访问信息在cache的比率,1-H表示未命中率
平均访问时间
实际例题:
由于主存与Cache以"块"为单位进行数据交换,而对于数组a[0][1]
我们可以根据地址信息来判断其在哪一个块中,我们可以将这一块的所有信息放入到cache中。
此时主存的地址可以分为块号、块内地址。
下面是接下来章节要学习并解决的问题:
三种映射方式:全相联映射、直接映射、组相联映射
如何区分Cache中存放的是哪个主存块?
此时标记号为0也是有一个问题,那就是主存地址是从0开始的,那么此时就会产生冲突!如何解决呢?
①主存块号与块内地址分布?
给定主存地址总空间256MB,行长为64B
256MB=228B,计算主存块号数即为228B / 26B = 222,即主存块号为22,块内地址为6。
②如何进行划分?
放主存中的第一块时,可以放入到cache中的任意一个块中。放入好之后会记录标记号(主存地址)以及有效位为1(表示已占位置)
③如何访问主存地址呢?
1、首先会使用主存数据的前22个在cache中标记进行匹配对比,若是比对相同,若是有效位为1,即表示cache命中。
2、若是不能够命中,根据有效位=0情况,表示是否可访问,若是为0则直接到主存中去找数据。
主存映射cache位置公式:主存块在cache中的位置 = 主存块号 % Cache总块数
存放流程:若是cache有0-7块,主存有0-222-1,按照规则来看,我们依次来放0、7两个主存块:
通过上面流程可以很明显发现一个问题:就是在分配主存的某一个块时,对应的cache位置被占用,而此时又有其他位置空闲,但是这个主存块就是非一个块不可,若是先前被人写了还是会直接上去覆盖掉!
缺点:其他地方有空闲Cache块,但是7号主存块不能够使用,空间利用率不充分。
关于标记存储内容的优化
引出:例如主存的前22个块号是0…01000,通过 % 7此时确定cache的位置为0,此时在cache中标记位即同样为主存的前22个块号0…01000,此时我们可以对这个标记位进行优化。
优化点:我们可以看到我们是%cache的块数,那么最终前22块号的最后3位就是我们的cache编号,此时我们可以省略前22个中最后的3位(也就是cache的块数二进制位数),可以优化为0…01,此时即可完成对应主存位置的标记,此时就只需要19位即可。
块内地址分布
以之前全相联映射的案例为主。
主存块号分为:19位标记+3位行号,块内地址为6块。
直接映射访存流程:
①根据主存块号的后3位来确定cache行。
②若主存块号的前19位与Cache标记匹配且有效位=1,则Cache命中,访问001110的单元。
②若是未命中或有效位=0,则正常访问主存。
确定主存数据在cache位置公式:所属分组 = 主存块号 % 分组数
主存块号分为:20位标记+2位组号,块内地址为6块。
标记位置优化点:由于分组数为4位,可用两位表示,此时我们可以省略在标号中的末尾两位去表示主存的位置。此时标记位只需要存储20位即可。
组相联映射访存流程:
①根据主存块号后2位确定所属分组号。
②若是前20位与分组内的某个标号匹配且有效位为1,此时cache命中。
③若是未命中,则直接访问主存。
全相联映射:只有Cache全部满了之后,才需要进行替换。
直接映射:无需考虑替换算法,可直接进行替换。
组相联映射:只有指定分组满了才需要进行替换,需要在分组内选择替换哪一块。
总结:全相联、组相联映射需要替换算法。
随机算法:若是cache已满,随机选择一块替换。
先进先出算法:若是cache已满,则替换最先被调入cache中的块。
近期最少使用算法(LRU):每一个cache块设置计数器,用于记录该cache多久没有被访问了。若是cache满,那么替换计数器中最大的。
流程:
计数器优化点:cache块的总数=2n,则计算器只需n位,且Cache装满后所有计数器的值一定不重复。
效果:LRU算法是基于局部性原理的,合理的,实际应用效果优秀。
发生抖动情况:若被频繁访问的主存块数量>Cache行的数量,则会发生抖动。
最近不经常使用算法(LFU):每一个cache块也有计数器,用于记录每个cache块被访问过几次,当Cache满后替换"计数器"最小的。
计数规则:新调入的块计数器=0,之后每被访问一次计数器+1,需要替换时,选择计数器最小的一行。
问题:曾经被经常访问的主存块在未来不一定用得到(例如:微信视频聊天相关的块),并没有遵循局部性原理,实际运用效果不如LRU。
根据cache是否命中来进行不同的处理。
写命中:全写法、写回法。
写不命中:写分配法、非写分配法。
为什么不讨论读命中、读不命中的情况?
写回法:当CPU对Cache写命中时,只修改Cache中的内容,而不立即写入主存,只有当此块被换出时才写回主存。
注意:对于指定cache块是否被修改过,我们可以使用一位脏位来表示其状态,1表示修改过,0表示没有被修改过。
好处与坏处:可以减少访存次数,但存在数据不一致的隐患。
全写法(或写直通法):当CPU对Cache写命中时,必须将数据同时写入到Cache和主存,一般使用写缓存。
好坏处:访存次数增加,速度变慢,但更能保证数据的一致性。
写缓冲:使用SRAM实现的FIFO队列(先进先出),写缓冲比较快。
详细过程:若是CPU命中cache中#2时,先会往cache指定块#2中写入,接着会向写缓冲中写入数据A,此时又命中了cache中的#1,同样会先写入到cache中的#1,接着向写缓冲中写入B。此时队列中顺序为AB,每次两步写完之后CPU就去干其他事情了,此时对于写缓冲中的数据则由专门的控制电路控制下逐一写回。
好处坏处:使用写缓冲后,CPU写的速度很快,若是写操作不频繁,则效果很好;若是写操作很频繁,可能会因为写缓冲饱和而发生阻塞。
写分配法:当CPU对Cache写不命中时,把主存中的块调入cache,在cache中修改。通常搭配写回法使用。
非写分配法:当CPU对Cache写不命中时只写入主存,不调入Cache,搭配全写法。
注意:只有读操作未命中cache时,才会将主存的这块地址调入cache。
最接近CPU的为L1,包含有Write Buffer。
举例:目前有L1、L2两级Cache,L2中保存的是主存中的一小部分数据,而L1中保存的则是L2中的一小部分数据。
对于各级cache中同样也需要保持数据的一致性,各级之间需要采用"全写法"+非写分配法来保持。
cache与主存之间传输以块为单位。
页式存储:一个程序(进程)在逻辑上被分为若干个大小相等的"页面",页的大小实际上是与我们主存块的大小是相同的,我们可以将一个4KB的程序分为4个页,可以将4个页离散的放入到主存中各个不同的位置。
若是一个程序被拆分为多块后离散存储到主存中,如何执行?引入逻辑地址、物理地址概念。
逻辑地址:程序员看到的视角,逻辑地址分为逻辑页号+页内地址,逻辑页号指的是对应程序分页的页号。此时我们可以将对应的逻辑页号去映射主存中的主存块号(逻辑地址映射物理地址),最终将物理地址+页内地址来进行拼接即可。
页表:数据存储在主存当中,CPU在进行地址转换的时候需要去查询页表,意味着CPU需要进行一次访存操作。页表中的一行表示为页表项,一个页表项对应着逻辑页号以及主存块号。
基于慢表的地址变换过程
地址变换过程:页表基址寄存器中存储了页表在主存中的地址
查询主存中的页表(慢表)流程:
①首先给出操作码和执行地址(000001 001000000011),拆分得到其中的逻辑地址(001000000011),逻辑地址=逻辑页号+页内地址(001000000011 = 00 + 1000000011)。
②查询主存中的页表,根据其中的逻辑页号来去匹配得到主存的物理地址 00-> 000000000010,将物理地址与页内地址拼接 = 000000000010 1000000011,即可得到物理地址。【查询页表一次访存】
③得到物理地址后我们会再先去cache中去进行查询。
基于快表的地址变换过程
上面写出的地址变换过程可以发现其中去页表里查询00这个逻辑页号时会去主存中找到这一块数据,那么若是之后访问该逻辑地址同样都是00,那么此时就不太高效,如何解决呢?
基于这个问题,我们来引入快表(TLB),再此之前我们存储到主存中的页表在这里可以称为慢表。引入快表之后,整个过程如何?
快表:存放在高速缓冲存储器中,同样包含标记、主存块号两个部分,一开始快表是空的
查询快表流程:
①在cache中查询快表指定的逻辑页号,若是有,直接获取到。【访问cache1次】
②若是没有,那么此时执行查询主存中的页表(慢表)的流程。【访存1次】
③查询得到逻辑页号+主存块号后即可存入到快表,可供之后再次使用。
注意快表与cache区别:
快表、慢表区别:
快表作用:加快地址变换的速度,减少一次访存。
虚拟存储系统:用户感觉到使用的容量比真实使用的物理容量要大。
例如:微信有1GB的数据,那么实际加载到内存中仅仅只是一部分,我们如何去界定这么一部分的数据呢?
存储器的层次化结构
主存-辅存:主要由操作系统完成。
Cache-主存:主要由硬件自动完成。
页式、段式存储器的比对:
段式存储器:按照功能模块拆分,每一段大小不一样。
虚拟地址结构:段号+段内地址
段表:在原先基础上增加段长,包含段首址、装入位、段长。
段页式虚拟存储器:先将一个程序分段,再进行分页。也就是首先按照功能模块分段,接着将每个容量不相同的段进行分页(每页容量一致)。
段页式虚拟存储将程序内存空间分为多个逻辑段,每个逻辑段又被进一步分为多个大小固定的页。程序访问内存时,首先生成虚地址,它被分成了两个部分:段号和页号。每个部分都表示了不同的含义。
具体来说,虚地址被分解为以下两部分:
然后,操作系统将逻辑地址转换为物理地址。在分段分页的虚拟存储管理系统中,逻辑地址中的段号和页号将被用于从段表和页表中检索对应的物理地址。最终,通过物理地址来访问实际位于物理内存中的数据。
整理者:长路 时间:2023.5.28-6.14