本文主要是介绍计算机组成.记忆力核心.存储器Memory,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
- CPU终究只是一个执行部件,它所执行的指令和数据来自哪呢?总不能由人来输入吧,我觉得键盘输入的速度肯定是比不上CPU运行的速度的
- 虽然根本上来说还是我们输入的,但我们不直接给CPU,而是放在一个地方存起来,也就是存储器。
- 存储器也是机器啊,机器之间交换数据的速度就快多了嘛
- 说得简单点,存储器就是为了存储处理器所需要的数据的指令的
- PS:图片要么是我自己画的(Visio很不错)、要么就是我从网上找的(比如一些器件、有水印的图表等等)
分类
- 一种东西总是可以被分类的嘛
按处理器是否直接访问
- 主存
- 也称内存。CPU所需要的指令数据都是直接来自内存的。计算机内所有活动的程序都是在内存中。
- 广义上一般说,只要是可以直接与CPU进行数据交换的存储器,都可以称之为内存。
- 所以就有这样的说法:内存分为ROM和RAM,即只读的部分和读写的部分。ROM部分存放一些固有的程序,如开机程序(BIOS芯片)等,通过这些让计算机先运行起来。
- OS程序是放在外存中的,由BIOS引导来读取外存的OS到内存中来运行。即便是裸机(空硬盘)也是有BIOS的,这个时候就通过BIOS引导到U盘、光盘等外存来加载里面的程序,可以是操作系统(如PE)也可以直接是操作系统的安装程序,进一步给电脑安装上OS。
- 关于计算机的启动,有篇很有名的博客,估计大部分人也都看过:计算机是如何启动的? - 阮一峰的网络日志
- 还有越来越好的UEFI启动
- 所以就有这样的说法:内存分为ROM和RAM,即只读的部分和读写的部分。ROM部分存放一些固有的程序,如开机程序(BIOS芯片)等,通过这些让计算机先运行起来。
- 狭义上来讲,内存指的就是RAM,也就是活动程序的所在地。作用是存放CPU的运算数据和要运行的程序,是CPU所能直接寻址访问的空间。
- 对于32位CPU来说,最大的访问空间是2^32bit换算下来就4GB,也就是说内存空间最大为4GB,即使换个8GB的内存条,但CPU也只能访问到4GB的空间。有点类似IPv4的不够用的情况。64位机倒不必担心这个问题,就好像IPv6。
- 辅存
- 也称外存,其数据需要先复制到主存中,才能被CPU使用。
- 我们所用的操作系统、各种软件如office、游戏等等,都需要先从外存复制到内存中,才能运行。
- 而我们在word里输入的文字等等,都是先存在内存里。内存是需要持续供电的,外存如硬盘则是利用磁性来长时间保存。word只有保存的时候,才会把内存的数据写入到磁盘中。
按访问方式
- 按地址访问
- 也就是最常见的存储器都是按地址来访问的。地址可以理解为一个个存储单元的编号,按存储单元的顺序,从1到n编号(编址)。我要访问哪个存储单元,给我编号(地址)就行。
- 按内容访问
- 也叫相联存储器。既然这样也就没有地址的概念,所以存储数据的时候不需要选择某个存储单元,而只是简单追加。但这就需要每条数据的长度相等。
- 访问的时候,给出一个相联关键字,用来和每条数据中的相应的部分数据来比较,如果相等则输出这条数据的其余的部分。
- 但因为每次访问都要和所有的数据进行一次比较,所以其访问的速度随着容量增大而急剧下降。不过在容量比较小的时候则具备很好的性能。
- 一般应用在CPU内部,如页式虚存所使用的TLB块表用来快速的确定页框号,Cache所使用的地址映像表来确实访问的主存地址下的内容是否被缓存。
按介质
- 半导体存储器
- 结构为半导体电路,也是由晶体管来实现,需要持续通电,访问速度快,通常用作主存。后面会详细讲。
- 磁表面存储器
- 通过载体表面磁性材料的两种磁化状态来表示二进制的0和1。
- 像常见的磁盘,以前的磁带。
- 存储容量大,便宜,可以长时间存储。
- 速度慢,毕竟还需要转换到电信号;机械结构复杂,像磁盘的磁针都精确到了纳米级;这也就使得容易坏,磁盘摔一下基本就over了。
- 光盘存储器
- 利用光学原理,对介质上面的凹凸表面对光照不同的反射来记录0和1。
- 传统DVD采用红色激光来读写,而蓝光盘则采用波长较短的蓝色激光来读写,所以蓝光盘在单位面积上能存储更多的信息,速度也快,也就是蓝光视频质量高的原因之一,毕竟光盘还是得能存下来那么大的视频文件才行啊。
- 由于光盘的物理特性,其先天对“恶意修改”“病毒”等免疫,所以在绝对不可修改的数据,如身份证、驾驶证、银行票据、保险票据、建筑档案、国防科技重要资料等行业应用中,以及不可存储与复制的数据(如有版权的光盘)的归档和日常数据管理,光盘已成为各级档案部门的唯一性选择。
- 铁电存储器
- FRAM,ferroelectric RAM,利用铁电晶体的铁电效应实现数据存储,是一种非易失性的存储器,同时具备RAM的快速读取和ROM的断电不丢失的特性
- 但由于铁电晶体本身的原因,超过一定次数则不再具备非易失性,但仍可当作普通的RAM使用。
层次存储结构
- 这么说来存储器不就很简单吗~添加一个存储部件用来与CPU交互不就可以了
- 不过现实往往不是那么简单。人们通常希望存储能容量大、速度快、价格低,集各种优点于一身,然而这些却通常自相矛盾
- 容量越大,地址越长,通常会速度慢
- 不过虽然价格会更高,但平均每位的价格反而随容量增加而降低
- 所以我们只需要解决容量大与速度快的相容性就好了
- 所以才有了层次结构的存储系统
访问数据的局部性原理
- 层次结构的基础就是局部性原理,有这个原理的支撑,层次结构的存储系统才能实现既容量大又速度快的
- 这个原理其实是个统计原理,不过其也是依赖于程序本身的特点:无论是取指令还是存取数据,处理器在一段连续的时间内访问的存储单元趋向于聚集在一个相对较小的连续的存储单元区域内
- 时间局部性:即CPU将要访问的数据就是刚刚访问的数据。比如程序中的一个循环,往往会对某个变量在短期内使用很多次。
- 空间局部性:即CPU将要访问的数据就在刚刚访问的数据的旁边。比如程序本身就是指令的连续序列,那么一条条指令就在空间上是连续的,同时也是按顺序来运行的。只有跳转等才会使得连续运行的指令在物理存储上是不连续的。
- 简单的理解一下,就是说,CPU运行一个程序,这个程序占用一定的内存空间区域,其所涉及的指令、数据也就被限制在了这个范围之内,而不是随机的分布在内存的整个空间。
层次结构的存储系统
- 典型的层次结构
- 以更为精简的 CPU -> Cache ->主存来分析
- 取Cache为M1,主存为M2
- CPU访问M1的时间为Tc1,访问M2的时间问Tc2
- 访问M1的次数为R1,访问M2的次数为R2
- 则有M1的命中率 H=R1R1+R2由于访问局部性原理所以 H 通常会比较大
- 整个的平均访问时间
- 如果M1访问不命中,则直接访问M2 Tc=H∗Tc1+(1−H)∗Tc2
- 如果M1访问不命中,则先由M2传入M1,再访问M1 Tc=H∗Tc1+(1−H)∗(Tc1+Tc2)
- 可见由于比较大的 H 所以 Tc 会更接近 Tc1 ,也就是访问速度快
- 如果M1访问不命中,则直接访问M2
- 进一步分析存储系统的层次结构
- 定义访问周期比 P=Tc2Tc1
- 定义访问效率 E=Tc1Tc
- 分析 E=Tc1Tc=Tc1Tc1∗H+(1−H)∗Tc2=1H+(1−H)∗P
- 我们总希望E可以越接近1越好,这也就意味着Tc和Tc1十分接近
- 相同的E值下,P越大,即两级存储的速度差别越大,H就必须越大。而H的提高是很困难的,所以就要求相邻两级的存储器的速度差别不能过大,否则整个存储系统的效率就不会很高。
- 定义访问周期比
半导体存储器
- 根据存储的信息是否可读/写,进一步分为
- 随机访问存储器RAM
- 可读可写
- 只读存储器ROM
- 事先写入,只能读取
- 随机访问存储器RAM
随机访问半导体存储器RAM
- 根据存储原理的不同,又分为SRAM(静态)和DRAM(动态)
- 详细的结构分析需要有一定的数字电路基础,,,,这一切对于我来说实在是太沉重了,,,所以我也只能稍微讲讲就好
组成
- 最小的单位为存储基元,只能存储一位的数据,即一个0或者一个1
- 若干个存储基元组成一个存储单元,使一个存储单元可以存放一个信息字,而对存储器的访问也是以存储单元为单位,即一次必须也只能对一个存储单元进行读写操作
- 所以有种存储技术——不如称为存储原则或存储方式——叫对齐,即保证一个数据(比如一个整数)是位于一个存储单元内,这样就可以在一次访存中进行读写,如果其被分为两部分存在两个存储单元,则需要两次访存。至于一个存储单元有没有那么大(int有32位),这就又牵扯到主存的扩展,即多个小芯片来联合成一个大芯片。主存那部分会讲。
- 扩展之后主存的一个存储单元的位数又称为存储字长,即一次访存的位数。存储字长是针对存储器而言。
- 机器字长:通常情况下与存储字长相等,但概念不一样。机器字长是运算器进行一次整数运算的位数。
- 指令字长:是程序一条指令的长度,一般设计为与存储字长相等,为的是在一次访存就可以获取一条指令。
- 不过这并不是必须的,只是这样可以提高速度,这里是指令集设计所需要考虑的部分,像变长指令通常会让短指令都小等于存储字长,而对于过长的指令超过存储字长也不是不能运行
- 一条指令一般为整字节的长度,为的是处理方便,也一定程度上防止了其跨存储单元存储(即对齐)。
- 若干个存储单元排列成存储单元阵列,在加上读写控制电路、地址译码电路和控制电路,就构成了一个存储芯片。
SRAM
- 根据 电流的开/关 来记录 0/1
- 开关元件有双极型和MOS型。
- 说双极型速度快但成本高功耗大,主要用于高性能计算机而不是普通的微型计算机。
- 查了半天也没查到介绍的资料,清一色全是MOS
- MOS型三极管
- 当W为高电位是,MOS管才导通,即R点与Vcc同电位。
- 6管静态RAM存储基元
- T5和T6为选中开关,当字线W为低电位时,T5、T6均未导通,表示未选中
- T1和T2为双稳态触发器,T3和T4为阻抗(尽管在我看来就是供电的)
- 当W为高电位,表示选中此基元
- 写入
- 写入1:位线b’加高电位,位线b加低电位,使得T2导通,T1截止
- 写入0:相反
- 读取
- 若b’为高电位,b为低电位,则读出1
- 反之,读出0
- 写入
- 由于Vcc电源保持高电位,所以在通电期间SRAM是会一直保持着信息
- 读取并没有破坏原先的存储环境,只是检测电位的高低,具有非破坏性读取
- 但所用MOS管较多,占用空间大导致相同面积下存储的数据小,成位密度低,且功耗大
- 单译码
- 只用一个地址译码器,直接选中一个存储单元
- 黑色实框表示一个存储基元,红色虚框为一个存储单元,蓝色虚框为存储单元阵列
- 16×4位意思是16个长度为4位的存储单元组成的存储芯片
- 但这本质上是一个线性的结构,从红色虚框(存储单元)的线性排布也可以看出。所需要的字线太多,n位地址需要2^n条线,来对应到每一个存储单元上。
- 双译码
- 将地址视为X和Y两部分部分,分别用X译码器和Y译码器进行译码,分别产生行选择信号和列选择信号,并充分发挥矩阵排列的优势
- 双译码256×1位存储芯片
- 黑色实框表示一个存储基元,由于一个存储单元只由一个存储基元组成,所以对这个256×1位的芯片而已,黑色实框同时又表示存储单元
- X选择器选中了16个存储单元(一行),进一步由Y选择器选择其中的一个存储单元
- 此时一个存储单元的选中信号需由 X和Y的与 来给出,即某行某列,也就对应了唯一一个存储单元
- I/O控制器给出读写信号D,且只有在Y选择的那一列,这一列的开关才是导通的,虽然给每一列都发送了读写信号,但由Y地址译码器控制着每一列的开关,保证了只能选择一列
- 非D线(即D上方加一个横线)在读时返回结果,写时写入结果
- 芯片整体
- 多个芯片组合在一起进行扩展才能达到足够大的容量和位宽.
- 对于每个芯片,其又有各种针脚来输入输出
- 如2114(1K×4位,即1024个存储单元,每个存储单元长度为4位)
- A0~A9为地址针脚
- I/O1~I/O4为数据针脚
- 非CS(CS头上一根横线,表示低电平为选中)芯片选择信号
- 非WE(WE头上一根横线,表示低电平为写,高为读)写命令信号
- Vcc电源引脚,GND接地引脚
DRAM
- DRAM与SRAM的区别在于,DRAM根据栅极电容上电荷的“有/无”来表示信息 0/1
- 单管动态存储电路
- 由一个MOS管和一个电容组成
- 字线W来控制选中状态
- 写入:字线加高电位选中
- 写入1:位线加高电位,电容C充电
- 写入0:位线加低电位,电容C放电
- 读取:字线加高电位选中
- 检测位线输出为高电位,读取1
- 检测位线输出为低电位,读取0
- 写入:字线加高电位选中
- 读取操作是破坏性的(检测高低电位需要电容放电,电荷会丧失),所以去读操作必须包含一个“重写/再生”的环节
- 且电容C上的电荷本身会缓慢的丢失,所以需要隔一段时间对电容补充电荷,即刷新。这里利用了读操作的“重写/再生”,即刷新一次就是对所有的存储单元进行一次假读取——不输出数据。
- 刷新操作是逐行进行的,而刷新操作会和实际的读写操作产生冲突,那么
- 集中刷新:在一个刷新间隔内,集中一段时间来刷新全部的存储单元,这段时间不能读写,就死掉了(死时间)。
- 分散刷新:即将对每行的刷新分散到每个读/写周期中:延长原先的读/写周期,前半段来读/写操作,后半段用来刷新。会使得读/写操作花费的时间变长,但没有死时间。
- 异步刷新:又是一个结合的产物。在一个刷新的间隔内,对每行的刷新均匀的分布在间隔中,将一整块的死时间分散开。
- DRAM的工作
- DRAM由于集成度的提高,芯片内存储单元的数量大大增加,这也就使得地址线也相应增加,但由于各方面的现在(尺寸、成本)等,芯片针脚的总数不能增大,所以DRAM的地址针脚个数为实际地址长度的一半
- 为此,访存地址也将分为行地址和列地址分别发送
- 为了区分行地址和列地址,又增加了两个控制线RAS和CAS分别控制行地址和列地址的接收
- 典型的2116(16K×1位)
- 16K=2^14,即地址总长为14位,行地址和列地址均为7位
- 通过行地址和两个行地址译码器,从两个64×128存储单元阵列(64行,每行128(2^7)个存储单元)中选取一行放到中间的128个读取放大器
- 通过列地址从读取放大器中的128个存储单元选中一个
- DRAM由于集成度的提高,芯片内存储单元的数量大大增加,这也就使得地址线也相应增加,但由于各方面的现在(尺寸、成本)等,芯片针脚的总数不能增大,所以DRAM的地址针脚个数为实际地址长度的一半
只读存储器ROM
这个玩意也要分类
- MROM(Masked ROM,掩模型ROM)
- 原理是根据每个存储基元中有无晶体管来表示“0/1”
- 可靠性高、位密度高、访问周期短,但是成本高,且不可更改
- PROM(Programmed ROM,可编程ROM)
- PROM的内容不是在生产的时候写入,而是后期通过某种方式来写入
- 熔丝烧断型:每个存储基元中有熔丝,通过选择性的熔断某些熔丝来进行编程
- PN结击穿型:基元中连接有PN结,选择性的击穿某些PN结来使其导通
- 同样不可更改
- PROM的内容不是在生产的时候写入,而是后期通过某种方式来写入
- EPROM(Erasable PROM,可擦除可编程ROM)
- 如浮栅雪崩注入型MOS管,出厂是不带电荷,不导通,表示1;加高电压击穿其中的PN结,导通,电荷积累在浮栅上,表示0,且由于二氧化硅的存在电荷不易消。
- 在紫外线灯的照射下,浮栅上的电荷将全部释放,恢复到全1的状态,就可以重新进行编程
- EEPROM(Electrically EPROM,可用电擦除的可编程ROM)
- 这个就是不需要外部设备来擦除而是直接用电
- 但每个存储单元用了两个NMOS关
- 基本操作
- 擦除:擦除电压Vpp,统一置1
- 编程:编程电压Vpp,由1变为0
- 读取:工作电压Vcc,输出数据
- 闪存Flash:变种EEPROM
- 存储基元采用一个CMOS管,密度高、速度快,且不易失
- 但是1:其擦除不像EEPROM可以在字节水平上,而是整块擦除
- 但是2:有效编程次数有限
- 但是3:擦除和编程所需要的时间较长
主存
- 系统程序等无需且不能改动的数据由ROM存放
- 活动程序由RAM存放
存储芯片来扩展
- 一个存储芯片来搞定4GB的主存?你想多了吧
- 单片存储芯片的容量和字长(存储单元的长度)一般不能直接满足实际需求,所以往往需要将若干个存储芯片连接在一起
- 位扩展:扩大存储字长,并联思想
- 1K4位(2114)×2=1K8位
- 字扩展:扩大存储容量(存储单元数量),串联思想
- 1K8位×2=2K8位
- 字位扩展
- 位扩展:扩大存储字长,并联思想
并与处理器相连
- 当处理器数据线数大于存储芯片的数据线数,就要进行位扩展,然后一一相连
- 当处理器地址线数大于存储芯片的地址线数,就要进行字扩展。此时处理器的部分地址线(如地位)可以直接与存储芯片相连,而其余地址线(如高位)则需要连接到片选译码器来决定选中哪一个存储芯片。
- 如:3-8译码器74138
- G1为高电位、G2A和G2B为低电位,表示译码器有效
- ABC为三位输入,高电位有效
- Y0~Y7为输出,低电位有效,且有且仅有其中一个输出
提高主存访问带宽
- 毕竟处理器还是太快了点
并行存储器
- 多端口RAM
- 如双口RAM,具有两套独立的读/写控制逻辑,分别有自己的地址总线、数据总线和控制总线,可以独立的对任何地址单元的数据进行读写操作
- 当访存地址相同时,需片内仲裁逻辑来决定顺序
- 多模块存储器:又分为
- 单体多字存储器:根据程序访问的局部性,读取相邻的存储信息
- 多个存储模块公用一套地址逻辑,典型如公用一个MAR,这样一访存地址可以取出从多个存储模块的相同地址单元中取出多个字
- 典型单体多字存储器
- 多体并行存储器:N个存储模块,各自独立的地址逻辑,只要连续访问的存储单元不在同一模块中,就可以相互错开1/N个周期来轮流的占用地址总线、数据总线和控制总线
- 也称“模N交叉存储器”
- 带宽提升为N倍
- CPU地址总线宽度要大于单个存储体,多出的部分当作体选信号,即选择哪一个存储体来访问
- 低位作为体号,会使地址上连续的指令、数据分散在不同的存储模块中,根据局部性原理,减少了访问冲突,提高了并行性。但可靠性差
- 高位作为体号,可靠性高,但相对来说冲突就没有那么低
- 混合交叉
- 整个空间分为M部,每部N体。
- 高Log2M位为“部号”,低Log2N位为体号
- 单体多字存储器:根据程序访问的局部性,读取相邻的存储信息
- 信息按边界对齐存储
- 就是对齐啦
- 对于N体并行存储器,不要跨行存储
- 规定存储地址为数据长度的整数倍
- 由于读取是基于存储单元的,,,,,,似乎也不可能跨存储单元除非因为太长….
高速缓存Cache
- 局部性原理的最佳体现
- 存储器墙的解决办法
- 其实缓存的思想被应用在很多地方
四大内容
1、地址映像:主存的数据如何存放到Cache中
2、地址变换:对于更长的主存地址如何转换到Cache地址
3、替换算法:一旦要写入Cache中的数据块按照地址映像规则发现没有空间存放了,应该如何选择数据写回主存来让出空间
4、写入策略:对于CPU要向主存写入的数据,如何和Cache相统一
Cache介绍
- 工作原理自然是局部性原理啦
- 主存与Cache之间的数据交换是基于数据块
- 主存普遍为模M交叉访问存储器,即在访问一个存储单元的同时,可以读取出包括它在内的M个存储单元的数据,这些数据就被作为一个数据块装入Cache。由于局部性原理,它们很可能很快就被用到。
- Cache与主存的结构可以分为
- 旁观式
- 透过式
- 旁观式
- Cache的一些概念
- 在Cache中存放一个数据块的区域称为槽
- 对于Cache的访问分为槽号和槽内地址
- 槽号:选择一个存放数据的槽(数据块)
- 槽内地址:选择具体槽内的哪个数据
- 主存地址
- Cache的工作
- 对于旁观式结构
- 经过地址变换之后,如果Cache中存在则直接访问Cache,否则直接访问主存
- 直接访问主存后会把这次的数据块写入Cache中,Cache已满则根据替换算法选择替换的数据块
- 对于透过式结构
- 经过地址变换之后,如果命中则直接访问
- 否则等待一个主存周期等主存把包含待访问数据的整个数据块写入Cache后再访问Cache
- 对于旁观式结构
地址映像和变换
- 确定主存的一个数据块要放在Cache的哪个槽内
- 均由硬件实现,速度快且不需要编程人员考虑(即对程序员透明)
- 借助“地址映像表”来实现
- 记录每一个Cache槽号与主存数据块之间的对应关系
- 一般采用相联存储器实现
- 全相联
- 主存地址分为块号和块内地址
- Cache地址分为槽号和槽内地址
- 由于一个数据块对应一个槽,所以槽内地址长度一致
- 块号一般要远远长于槽号
- 地址映像表记录槽号与块号的对应关系
- 地址映像
- 任选一个槽!
- 写入的时候要在地址映像表里添加一条块号与槽号的记录
- 地址变换
- 查表费时间长,而且地址映像表一般比较大,用相联存储器实现的成本比较高
- 直接映像
- 主存地址分为块号和块内地址
- Cache地址分为槽号和槽内地址
- 地址映像
- 对于主存的一个块,其只能存放在Cache的一个槽内
- 一般截取块号的一部分直接作为槽号
- 选择截取高位或地位作为槽号均可
- 标签直接写入地址映像表中以槽号为地址的位置,也就是说地址映像表中以地址的形式体现槽号,一个地址写一个标签体现了槽号与块号的对应关系
- 地址变换
- 根据通过主存地址截取出Cache地址后剩下的标签,来查找地址映像表
- 如果存在相等的记录且有效,则直接使用Cache地址访问Cache
- 如果不存在或失效则直接访问主存(旁观式)或等待主存写入Cache(透过式)
- 组相联
- Cache分为G个组,每组B个槽
- 主存分区,每个区分为G组,每组B个块,即每个区的大小和Cache相等
- 主存地址分为区号、组号、块号、块内地址
- Cache地址为组号、槽号、槽内地址
- 地址映像
- 组与组之间直接映像,主存组号和Cache组号长度相等
- 主存中的块与对应组内的槽是全相联,但主存的块可以来自相同组号的不同的区
- Cache的每个组都有自己的地址映像表,来记录组内的槽号和主存区号+主存块号之间的对应关系。
- 一般比较小,可直接由相联存储器实现。
- 地址变换
- 根据主存组号,以其为地址选出该组对应的地址映像表
- 查找地址映像表,如果找到区号+块号,则取出对应的槽号,进一步构成Cache地址来访问
- 否则该干嘛干嘛
- 其实可以看出组相联的本质是从主存块号截取一段组号来直接对应到Cache的一组,其余的作为标签。
- 所以可以直接截取低位为组号,剩余的高位作为标签
- 段相联
- Cache分为G个段,每段B个槽
- 主存分段,每段也为B个块
- Cache地址分为段号、槽号和槽内地址
- 主存地址分为段号、块号和块内地址
- 主存的每个段有自己的地址映像表,记录段内块号与Cache段号的对应关系
- 地址映像
- 段与段之间全相联
- 主存段内的块与Cache段内的槽直接映像
- 地址变换
- 根据主存段号进行相联比较,选出该段的地址映像表
- 以段内块号作为地址访问地址映像表,读取对应的Cache段号
- 获取Cache地址
替换算法
- 最近最少用算法,LRU
- 每个槽一个计数器
- 被复位的时候清为0
- 被访问的时候置为最大值
- 其他槽被方位的时候减1,为0的话则不变
- 替换是选择所有计数最小的其中一个替换
- 每个槽一个计数器
- 最不常使用算法,LFU
- 选择过去一个时间段内访问次数最少的数据块
- 代价比较大
- 先进先出FIFO
- 选择存放时间最长的槽
- 随机替换Random
写入策略
关键是保持Cache和主存中内容一致
写穿法(Write-Through,WT)
- 写命中时,同时写Cache和主存
- 写不命中
- 按写分配:写入主存并把相应数据块调入Cache
- 不按写分配:只写入主存
- 写回法(Write-Back,WB)
- 写命中时,只写Cache;当被写的块要被替换的时候,才将这个修改的值写回主存
- 写不命中
- 按写分配:把被写的数据所在的数据块调入Cache,并对Cache进行写入(等到被替换就自然写回主存)
- 在多处理器系统下,要保持多个处理器其自己的Cache和共享数据的一致性就麻烦许多
- Cache一致性协议
- 目录协议:保存共享数据块的状态和相关信息
- 监听协议:每个Cache除了保存数据备份外,也保存每个块的共享状态。Cache控制器通过监听总线来判断自己的Cache内是否有总线上请求的数据块
- Cache一致性协议
Cache优化
- 降低Cache失效率
- 失效分为三类
- 强制性失效:首次访问某块,其不在Cache中
- 容量失效:全相联,某块被替换后,又被访问的失效
- 冲突失效:组相联或直接相联,某块被替换(即便有空槽)后又被访问
- 调节Cache块大小
- 块大小取决于下级存储器的延迟和带宽
- 高延迟高带宽,可采用大Cache块,因为只需要增加一点点失效开支,就可以缓存许多数据
- 低延迟低带宽,则采用小Cache块
- 提高相联度
- 但同时也会增加相联比较的时间
- Victim Cache技术
- 在Cache和主存之间增加一个小的全相联的Cache
- 其中存放被替换出来的块
- 失效时先检查Victim Cache中是否存在
- 硬件预取
- 由Cache之外的硬件完成,在CPU提出访问请求之前将数据和指令缓存到Cache中
- 编译器控制预取
- 在程序中加入预取指令
- 编译器优化
- 数组合并:独立数组合并为复合数组,使一个Cache块包含更多的数据
- 内外循环交换:修改循环顺序,提高局部性
- 循环融合:多次循环合并到一起,使Cache的数据在替换之前就可以被访问
- 分块:大矩阵分为子矩阵,提高局部性
- 失效分为三类
- 减少失效开销
- 写缓冲:写穿和写回中,都需要把Cache块写回主存,则先写入一个写缓冲器;当写缓冲器写回主存时,CPU可以干其他的事
- 写合并:检查写缓冲器中现有的数据是否和将要写的数据是相同地址,如果是则合并
- 读失效优先:写缓冲可能包含最新的值,则需要在读失效的时候先检查写缓冲器中是否有匹配的数据
- 请求字处理:Cache的一个块往往只有一个字是CPU所需要的,所以可以提前把该字发给CPU,而不必等待整个数据块写入Cache中
- 多级Cache
- 非阻塞Cache:允许在Cache失效时继续服务其他访问
- 减少Cache命中时间
- 容量小,结构简单的Cache
- 虚拟Cache:对于采用虚存的计算机,其访存地址为虚地址,需先转换为实地址,在进行地址变换;虚Cache可直接使用虚地址进行地址转换
- 不同进程可能使用相同虚地址访问不同实地址,所以需要进程标识辅助
- 流水化访问
- 多体Cache
- 路预测:由一些预测位,保存下一次访问Cache的这个组时所命中的Cache块。
- Trace Cache:在Cache中缓存的不是主存中的静态指令序列,而是处理器执行的动态指令序列
虚拟存储器
- 从固定分区
- 到可变分区
- 到突破思维的段式存储管理:一个程序完全没必要再内存中连续存放
- 到页式存储管理:进一步的分散存放
- 再到进一步突破思维的虚拟存储器:一个程序完全没必要全部存放在内存中
嗯。差不多就这样。
这篇关于计算机组成.记忆力核心.存储器Memory的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!