3.存储系统
存储系统
1.内存
- 首先来看一下计算机中的存储结构图

在计算机中,存储空间是以图中的结构来构成的,最上面的是寄存器,然后就是三级高速缓冲区(cache),然后就是内存(主存),可以注意到一个点就是 我们的高速缓冲区都是由SRAM构成的,而内存都是DRAM构成的
1.RAM

- RAM主要分为SRAM(构成cache) 和 DRAM(构成内存)
1.DRAM和SRAM的区别
首先先来看一下两种RAM的区别

- 在硬件层面上,DRAM组成部件是一个晶体管和一个电容,而SRAM组成部件是六个晶体管
- 因为DRAM中的存储部件是有电容的,所有在即使在通电的时候也需要来对其进行充电,也就是刷新

- 其差别表如图,第一个就是晶体管的数量,所有就有了DRAM的花费是SRAM的千分之一,而运行时间确实DRAM的十分之一,这也是为什么SRAM做高速却存储空间小的高速缓冲区的原因. 同时DRAM无法稳定保持数据并且是敏感(其实就是对干扰因素敏感),而SRAM就相反
2.DRAM的种类

- 对于DRAM主要分为上三种,SDRAM(同步DRAM)、DDR(DDSDRAM,双倍速率同步DRAM)、LPDDR(低效率双倍效率同步DRAM)
- 现在计算机中主要使用DDR,而手机和一些嵌入设备中使用LPDRAM(同级的DDR中,LPDDR效率低于对于的DDR)
3.DRAM的数据存取

- 注意,在题目中16 * 8, 16是指总容量,8是指每个存储单元的大小
- 在csapp中把每一个小的存储单元称为超级块

- 当我们要读取一个单元位置的数据时,我们先将行地址传入,然后对于的行放入行缓冲区;再将类地址传入,此时在对于缓冲区确定对于列,数据单元的数据通过数据总线传输到 内存控制器(DMA)
- 即先行地址,后列地址
- 为什么我们不一次性传入行和列下标据直接得到数据单元的位置? 答:因为芯片的引脚数量非常珍贵,每个芯片上面的引脚的数量是有限的,若要直接使用 "数组型"的存储单元 就需要增加引脚的数量,这样就会严重增加芯片的成本,所以为了避免增加引脚的数量,我们牺牲一部分性能使用这种方式读取数据,使用这样的方式可以省一半的地址
- 因为引脚资源稀缺有限,使用这样的方式可以节省一半的地址
4.DRAM组

- 若一个DRAM无法组成所需要对于存储单元的DRAM时,就可以将其"并联"扩大其存储单元的大小,当然若需要将总容量扩大时将DRAM 或者 DRAM组串联即可,这一点在真题中尤其体现
5. 交叉编译

- 在上面的交叉编译中,每一个bank都是一个DRAM组 或者 DRAM存储对于的数据,在传入地址时低位的地址是选择对应bank的标记,高位才是对应数据的地址
- 例如: 00 表示bank0,01表示bank1,10表示bank2,11表示bank2……

- 对应存储数据时,根据DRAM(组)的数量,每次将低位的选择位 % DRAM(组)的数量然后在根据对应高位地址将数据存储对应的位置
2.ROM
1.ROM的特性

- 注意,由于历史原因以前的ROM只能进行读数据操作,但是现在的大部分ROM都是可以读写操作的
- ROM是在断点之后会保持数据,RAM并不会保持数据,这是ROM和RAM最大区别
2.ROM的种类
- 需要注意的是,闪存的读写速度并不是相同的,当一个数据块被写过之后就会被标记位dirty(脏的),再次进行写操作时会重新将数据擦除之后再进行写操作,所以说闪存的读数据速度要快于写数据
2.Cache

- cache高速缓冲位于cpu中,由于cpu与主存之间的速度差距比较大,所以在cpu中需要一个"中间件"原来缓冲,所以就有了cache的存在,用于存储使用频率较高的一些数据
1.cache的结构

高速缓冲中的组成
- 在cpu中的cache中是由多组cache组成的高速缓冲区的,每行cache由三部分组成: Valid(标记当前数据是否有效,1bit)、Tag(标记位,通过比较对于数据判断是否要询问改行数据)、最后一部分就是数据块(其大小根据题意来看,单位是bit)
- 在高速缓冲区中,有多组数据集合,而这些集合中又是以多行cache组成的,组数都是以2的幂为其大小
CPU传输的命令
- 其传输的地址命令也是有三部分组成:Tag(用于对应cache行的标记位,看是否匹配)、 Set index(用于确定具体cache行在哪一个组内,与缓冲区可以存储的空间大小 和 数据块的大小有关)、Block index(其存储的是偏移量用于查找数据块中的数据,具体大小就是数据块的大小)
2.cache的构成类型
1.直接映射

- 特点:对应直接映射方式,每组只有一个cache line
2.组相联

- 特点:对应组相联方式,每行有多个cache line
3.全相联

- 特点:对应全相联方式,一共只有一组该组中有多行cache line,对于这中方式地址总线中可以是没有 Set index的
3.数据查找
对于数据查找步骤主要有三步:
- 组选择
- 行匹配
- 字抽取
当不满足上面步骤时,就是cache miss,即读未命中;满足就是cache hit,即读命中
1.组选择

- 组选择,在地址总线传来的指令中的 Set index中的数据来找到对应的组行
2.行匹配

- 行匹配,先判断Valid,判断当前cache line行的数据是否有效,若有效—> 在将指令的Tag与找到的cache line中的Tag进行匹配
3.字抽取

- 字抽取,根据Block offset中存储的偏移量找到cache line中对应的数据
4.注意
- 对于全相联来说,是不需要Set index这个数据单元的,如下图

4.写数据方式

- 对于读操作来说有命中和未命中,而对于写操作来说也有写命中和写未命中
1.写命中
写命中表示数据已经在cache内
- 写穿透:数据虽然在cache内,但是数据会直接被写回主存
- 写回:数据在cache内,先将cache内的数据改写,当cache满了之后再将所以数据写回主存
- 注意:在使用写回的写命中方式时,cache line 中要添加一共Dirty位(脏位)
2.写不命中
写不命中表示数据不在cache内
- 写分配:数据不在cache中,先将数据写道cache中,再对cache中数据进行修改
- 写不分配:数据不在cache中,直接对该级cache的下一级存储(下一级cache(一共有三级cache),或者是主存)
注:在计算机中写不分配和写穿透来匹配使用
5.LRU算法
- 最近最少使用算法(Least Recently Used),LRU算法
- 其实就是为每个cache分配一共 old bits,每一次访问所以 old bits的数都减一,然后如果所有cache已经满了,就将old bits中最小的值替换,然后将其替换为 行数 - 1,这个也是 LRU特殊分配为的位数 log2(行数)
- 如果一开始为空,就直接替换为 组数 - 1

- 一开始cache line都为空,然后直接覆盖在cache line中且将LRU中的值频率值设置为3,下一继续找到空的cache line覆盖,记住每次操作都要将LRU中的值减一(如果有的话)
- 直到所有的都满了,像第三列,此时所有cache都满了,将最小的cache line中的cache中数据覆盖掉,并将其LRU中的值替换从 行数 - 1,然后其他的LRU值减一,结果就是第四列
- 注意:在使用LRU算法时,cache line(Valid、Tag、数据块)会加上LRU的计数位,其大小就是 log2(行数)
3.虚拟内存
1.基本概念
1.从物理地址到虚拟地址
-
在以前没有虚拟地址概念的时候,计算机用的都是直接访问物理地址进行数据查询

- 但是由于内存与磁盘之间的速度差距很大,直接物理寻址会极大的降低效率,所有后来便发明并使用了虚拟地址进行寻址
- CPU中MMU(内存控制单元)来进行将CPU所给的虚拟地址转换成物理地址再交给cache,通过cache进行数据查询,将所需要的数据传递CPU
2.地址空间

- 地址空间规定了,系统中规定的虚拟地址的位数,同时物理地址的位数也在这规定
3.虚拟页、物理页、页表
1.虚拟页

- 在计算机中,虚拟地址都是分页的,通常每一页的大小是4k(或者8k)
2.物理页和虚拟页的关系

- 每个虚拟页都有三个状态:
- 已缓存(Cached),这种状态下vp地址和pp地址已经开始存在映射关系
- 已分配,未缓存(Uncached),这种状态下该虚拟页已经别分配但是还未进行映射关系
- 未分配(Unallocated),这种状态下的虚拟页未分配
注:访问后两种状态下的虚拟页或造成缺页现象
3.页表
- 页表是虚拟内存中非常重要的数据结构,主要存储虚拟页和物理页之间映射关系的表

2.虚实地址转换

- 虚拟地址主要由虚拟页号(VPN)和 虚拟页偏移量(VPO)组成,其中虚拟页号用于通过页表找到对应的物理页号,其中物理页偏移量和虚拟页偏移量位数相同,所组成的物理地址就是传输给cache的地址
- 虚拟页偏移量大小由 虚拟页的大小 决定,比如4KB的页,其虚拟页偏移量大小为12bit
- 注:页表所存储的位置在页表基址寄存器中
3.取址方式
1.直接虚拟寻址

- 当前虚拟地址所对应的物理地址在内存中时(寻址命中),MMU将对应虚拟地址进行转换,直接将转换得到的物理地址传输给cache,由cache解释物理地址,并将数据传输给CPU

- 当虚拟地址所对物理地址不在内存当中时(寻址未命中),MMU发出错误信号,并由内存将磁盘中对应物理地址取出,并放入内存中,再进行寻址命中的操作即可
2.TLB虚拟寻址
- 由于每次直接直接访问的消耗比较大,所有在CPU中加入了TLB这样一个页表,其本质就相当于一个页表缓冲区,TLB和cache一样都是由SRAM构成

- TLB命中,直接在TLB页表中找到了对应的映射关系

- TLB未命中,在TLB页表中没有对应的映射关系,然后MMU会再到内存 或者 磁盘(内存中也没有时)当中虚招对应的物理地址
4.取址过程
1.从虚拟地址到物理的过程

- 在页表中寻找对应物理地址时,会将虚拟页号分成 TLBT(TLB Tag,比较位)、TLBI(TLB index,组下标),就类似于在cache中寻找对应的cache line一样

- 首先,通过对应的VPN分解成TLBT 和 TLBI并找对应的PPN(物理地址数字),可以时在页表中找到也可能在多级也表种找到,然后就获得了物理地址

- 如果TLB Miss,会到低一级的cache或者主存中找更新页表项,然后获得物理地址,之后将物理地址传出给Cache,然后进行Cache的访问(组选择、行匹配、字抽取),结果会Cache Hit 或者 Cache Miss,最终获得到CPU所需要的数据
2.为什么需要多级页表

- 对于常见的页表大小(4KB),32位的机器中虚拟页的个数就有2^20个,如果每个页表项(页的组成单位)大小为4b,一个页表总共大小就是4MB,而在操作系统中,每个进行都是要为其分配一个页表的,所有直接分配页表空间占用非常庞大
3.TLB查询到Cache询问(地址翻译)

- 一个虚拟地,,接下来会将其转化成对应物理地址并进行 TLB查询 和 Cache查询

- 在TLB的页表中找到对应的PPN,物理地址数

- 组成对应物理地址,分为Tag、Index、Offset

- 再从Cache中找到对应的数据块,将其传回CPU
总结:物理地址 和 虚拟地址的偏移量其实是一样大小的,有对应关系
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现