存储器概述
现代计算机以存储器为中心,他是计算机中存放指令和数据的主要部件
- 存储器的容量越大,能存储的信息越多。
- 提高存储系统的访问速度,是提高计算机处理信息速度的重要措施。
开发具有大容量、高速度和低成本的存储系统是计算机技术发展的关键目标之一

两张图复习完所有知识点


存储系统的层次结构
金字塔图
存储系统为了平衡速度、容量和成本,现代计算机采用了分层存储体系结构,从最快速但容量有限的 寄存器 到容量大但速度较慢的辅助存储设备,形成了存储层次结构

越靠近金字塔上层的容量越小但速度越快,越靠近金字塔下层的容量越大但速度越慢。
计算机的存储系统包含以下层次:
-
寄存器 (Registers):
- 寄存器 是位于处理器内部的最快速存储单元。
- 它们提供极快的数据访问速度,但其容量非常有限。
-
一级缓存 (L1 Cache):
- L1 缓存位于处理器内部,比 寄存器 空间稍大,速度比 L2 和 L3 Cache 更快。
- 它通常分为 数据缓存 (用于存储数据)和指令缓存(用于存储指令)。
-
二级缓存 (L2 Cache):
- L2 缓存比 L1 缓存大,并且位于处理器和主内存之间。
- 它的速度比 L1 慢,但比主内存快。
-
三级缓存 (L3 Cache):
- 在某些系统中,还有 L3 缓存,这是一种更大但速度更慢的缓存。
- 它位于 L2 缓存和主内存之间,旨在进一步减少对主内存的访问。
-
主存 (RAM):
- 就是我们常说的内存,比缓存慢,但比硬盘快得多,并且容量比缓存大。
- 主存 用于存储正在运行的程序和当前使用的数据。
-
辅助存储 (如硬盘驱动器或固态驱动器):
RAM
半导体随机存储器的英文为 Semiconductor Random-Access Memory ( RAM )。
首先说一下这个名词中的几个部分:
- 半导体:这种存储器使用半导体材料(如硅)制成。晶体管是构成半导体存储器的基本组成部分。
- 随机:随机的意思是随机访问,意味着可通过几乎恒定的时间访问存储器中的任意位置,它与其他存储技术(如磁盘或磁带)不同,后者需要按顺序访问数据。
随机存储器主要分为 SRAM 和 DRAM 两种。
SRAM
SRAM(Static RAM,静态随机存取存储器)使用触发器(通常由 4-6 个晶体管组成)构成存储器的基本存储单元,存储每个比特的数据,如下图所示:

只要电源持续供应,数据无需刷新即可保持稳定。
SRAM 通过将触发器组织成二维阵列构成存储器,每行连接一个字线(Word Line),控制该行所有单元的访问。
每列连接一对位线(Bit Line),用于传输数据。
SRAM 主要用于 CPU 缓存(L1/L2/L3 Cache)、寄存器、嵌入式系统中的小型高速存储。
DRAM
DRAM(Dynamic RAM,动态随机存储器)使用 1 个晶体管和 1 个电容器(1T1C 结构)构成存储器的基本存储单元,存储每个比特的数据。
- 电容器存储电荷,表示 1 比特数据(有电荷为 1,无电荷为 0)。
- 晶体管作为开关,控制电容器与外部位线(bit line)的连接,读写数据。

与触发器不同,电容器具有 动态特性,会随时间漏电,导致数据丢失,因此需要 定期刷新(通常每几毫秒)以恢复电荷。
DRAM 和 SRAM 的存储阵列在宏观上类似,都采用二维矩阵结构,通过字线和位线实现随机访问,主要区别在于基本存储单元的不同:

它以低成本和高容量著称,主要用于 计算机主内存(如系统 RAM)、显卡内存等。
行列复用
需要注意一点,绝大多数 DRAM 芯片的引脚都采用了 采用了 “行列地址复用” 的方式。
- DRAM 芯片内部存储单元是一个二维阵列:
- 行表示字线。
- 列表示位线。
- 如果直接给每个单元提供地址引脚,需要 log₂(行数) + log₂(列数) 个引脚。
- 例如: DRAM ( 个字,每个字 ),如果阵列是 256 行 × 256 列,就需要 16 根地址线。
- 但在 20 世纪 70、80 年代,封装引脚数量有限,无法承受那么多地址线。
于是,引入了 行列地址复用(Address Multiplexing):
DRAM 行列复用实例
假设有一个 16M × 4bit 的 DRAM 芯片:
存储单元总数:。
单元阵列:4K 行 × 4K 列(因为 )。
需要地址位数:
- 行地址:12 位()
- 列地址:12 位()
如果不复用,要 根地址线。
如果复用,只要 12 根地址线,行列分时复用即可。
实际上就把引脚数量减半。
- 芯片的外部只提供 log₂(max(行数, 列数)) 根地址线。
- 地址分两次送入:
- 先送行地址(RAS,Row Address Strobe 信号有效时锁存)
- 再送列地址(CAS,Column Address Strobe 信号有效时锁存)
但是 SRAM 一般不使用行列复用:外部地址线一次性给出完整的地址,直接解码到存储单元。因为 SRAM 容量较小且速度有限,所以引脚数量不会太多。
总结
Caution
实际题目中,只要涉及到 求 DRAM 地址引脚的 无一例外 默认使用 行列复用
因此选择题中的 地址引脚计算 要先看 芯片种类,再用对应方法求解
RAM 比对
SRAM 和 DRAM 对比如下表所示

Flash 存储
Flash 存储器是一种 非易失性 的电子存储设备,它利用半导体技术来存储数据。通常用于长期数据存储,如 USB 闪存驱动器、固态硬盘(SSD)和移动设备的内部存储。它在读取速度上比 RAM 慢,但优于传统的硬盘驱动器(HDD)。
Flash 存储器使用电子方式来擦写和重新编程存储单元。这意味着可以通过电信号快速擦除和写入数据。数据存储在小型存储单元中,每个单元由浮动门晶体管组成。这些晶体管可以保持其充电状态,从而代表不同的数据位。
Flash 存储主要分为 NAND Flash 和 NOR Flash 这两种类型。
ROM
ROM(Read-Only Memory)是一种 非易失性 存储设备,主要用于永久性地存储数据。
ROM 主要用于读取操作。虽然早期的 ROM 在制造过程中就已经被编程,不能修改,但现代的 ROM(如 EPROM 和 Flash 存储器)可以被重新编程
ROM 常用于存储固件,这是一种软件程序,直接嵌入在硬件设备中,用于控制设备的基本操作。例如,BIOS(基本输入输出系统)通常存储在 ROM 中。
注意一下 ROM 和 RAM 的对比如下:

ROM 的类型主要了解 EPROM 和 CDMROM 这两种:
-
EPROM
EPROM 可以通过紫外线照射来擦除数据,然后重新写入数据。写入数据和擦除数据都较为繁琐,且需要物理操作。常用作电脑的 BIOS 芯片,支持随机存取。 -
CDROM
CDROM 是一种光盘存储设备,数据在生产时一次性写入,不能被修改(只能读取)。
可以明显看出, ROM 以及 RAM 都是 半导体型存储器,即 随机存取存储器
主存
受集成度和功耗等因素的限制,单个芯片的容量不可能很大,所以往往通过存储器芯片的扩展技术,将多个芯片做在一个内存条上;
然后由多个内存条 以及主板上的 和 芯片组成一台计算机所需的内存空间,再通过系统总线和 相连
其中, 与 在主存中 统一编址
MAR 位数等于 地址线位数,MDR 位数等于 数据线宽度
Caution
注意,MAR 的位数由 地址线根数 或 最大寻址空间 决定
而实际存储容量 由 存储芯片的数量和规格 决定
讲故事时间
打个比方:你盖了一栋大楼(地址空间),规划了 64 个房间(64MB),所以你需要 6 位数字的门牌号(MAR = 26位)。
但是,目前你只装修好了 32 个房间(32MB)并搬进去住了。
即使你只住了 32 个房间,你的门牌号依然得预留出 6 位,否则未来你想装修剩下的房间时,门牌系统就乱套了。

单译码结构

双译码结构

可以看出,双译码结构下 虽然 地址位数 和单译码结构一致,但是 地址线个数 明显减少了
辨析概念
分析 行列复用 和 双译码结构 需要明确两个技术的用途
双译码(又叫行列地址译码)是为了减少译码驱动线的数量,让存储阵列排列更整齐。
地址引脚复用是为了减少芯片的腿(引脚)的数量,让芯片变得更小。
必然性:如果你使用了地址引脚复用(分时传送),那么你的存储芯片内部一定是双译码结构(因为地址是分行列传进来的,内部必须按行列去解码)。
非必然性:如果你使用了双译码结构,却不一定用了引脚复用。比如很多 SRAM 芯片,它内部是行列式排列(双译码),但它的行地址引脚和列地址引脚是分开的,同时送入,不复用。
总结对比
DRAM 芯片
DRAM 芯片是一种 动态随机存取存储器,通过 1T1C(1 晶体管 +1 电容器)存储单元以行列矩阵形式组织数据,依靠电容器电荷存储比特,需定期 刷新 以防止数据丢失。其 高容量、低成本 特性使其广泛用于计算机 主内存。
写操作

读操作

底部的 灵敏读出 / 恢复放大器 就是 行缓冲器
题目中一般会问,行缓冲器的容量为?
答: 先将 DRAM 构造成一个 行列矩阵,接着 将对应存储单元的位数 乘上 一行的字数
得到的数 就是 其容量
对比

动态刷新的概念

对于 CPU 来说,刷新操作和读操作是一样的;因此会和 的访存冲突,会有访存 ”死时间“。
刷新方式
低优先级
DRAM 刷新方式简单过一下就行,留个印象,没有直接考察过。
DRAM 的刷新方式包括:
- 集中刷新(Burst Refresh),暂停数据访问,在短时间内快速 刷新所有行,效率高但延迟大;

- 分散刷新(Distributed Refresh),将刷新操作均匀分布在时间段内,与正常访问交错,延迟小但控制复杂;

- 异步刷新(Asynchronous Refresh)将集中刷新和分散刷新结合而来的刷新方式,由外部控制器根据需要触发刷新,灵活但依赖控制器设计。

这些刷新方式的具体对比如下表所示:

刷新过程


据此,可以得出 DRAM 的物理刷新过程
多模块存储器
利用多个结构完全相同的 存储模块 的并行工作来提高存储器的 吞吐率
中优先级
这一节还是蛮重要的,考察得不算少,经常将 多体交叉存储 和 主存容量的扩展 放一起考察。
单体存储器
按同一地址码并行访问各自对应单元,每一个单元为一个字,每字 m 位。可以同时选中存储器的 n 个单元,可以将带宽提高 n 倍。
仅做简单了解,这里不详细说明,考试重点在 多体交叉存储器。
多体存储器
在 多体交叉存储器 的设计中,为了提高存储系统的并行性和带宽,常采用 交叉编址 的方式将主存划分为多个 存储体(memory bank)。根据地址在各存储体之间的分布方式,交叉编址又分为 高位交叉编址 和 低位交叉编址 两种。
高位(连续)编址
在 高位(连续)编址 中,地址的高位 用于选择 存储体,低位 表示在该存储体中的偏移地址。
例如:若系统有 4 个存储体,地址空间大小为 4n,则:
- 地址 0 ~ n−1 存储在 M0;
- 地址 n ~ 2n−1 存储在 M1;
- 地址 2n ~ 3n−1 存储在 M2;
- 地址 3n ~ 4n−1 存储在 M3。
也就是说,一整个存储体连续存储一段地址空间,相邻地址数据往往在同一个存储体中。如下图所示:

为什么高位多体不能并行访问主存模块?
低位(交叉)编制
一般情况下我们 incline to 所有的的主存模块在总线上工作
所以又诞生了 一个 低位多体交叉 存储器,此时 存储器的 主存地址变成了
在 低位交叉编址 中,地址的低位 用于选择 存储体,高位 用于标识该存储体内的偏移地址。
主存地址 = 块内地址 模块地址
题目中称作: 体内地址 体号
这样就实现了 相邻地址分散存储在不同存储体中 的效果:

注意
这里的存储器模块 每 个周期之后的 才是真正传输数据的时间;在流水线的时间轴上, 时间才是涵盖第一个模块从“收到地址”到“数据传回 ”的完整过程。
:读数据 ; :传数据
其次,存储单元在存储模块中也不一定是连续的,从任意地址 (某个模块的某个存储单元) 开始顺序存取。
连续 次 流水线
- 第 1 轮流水线:结束时间是 。
- 第 2 轮流水线:你能不能紧跟着第 1 轮后面就开始?不行! 因为第 2 轮的第一步是要再次访问“模块 0”。而模块 0 必须等到第 时刻才空闲出来。
- 所以第 2 轮的模块 0 只能从 时刻开始,结束于 。
- 第 轮流水线:同理,第 轮的第一个模块(模块 0)必须等到 时刻才能开始,并在 时刻结束。
根据上图,也能够推出,在第 时间段,第二次流水线开始了
自己的理解
这里的 是接力赛中 每个存储模块从总线到 需要的总耗时时间,一旦 到达,接力棒(传输权限)交给下一个准备好的存储模块 ,为了保证每次传输都能到达最快时间,需要让 在刚好传输完的同时将接力棒交给 !!!
BOK 解释
轮流启动

利用了后面的流水线访问的 思想
同时启动

这里用到的思想是 位扩展
总线传输周期
轮流启动
区分 传输周期
准备数据以及传送到 的周期
存储器准备数据周期 \qquad$$T_{2}=T+(n-1)r
这里我们一般都将总线传输周期看作
同时启动

主存容量的扩展及其连接
虽然单体存储芯片的容量和字长在不断扩大,但是在实际应用的过程中,仍然会出现芯片的容量或者字长满足不了应用的情况,因此就有了 存储扩展 的需求;
假设存储芯片的存储字数为 M ,字长为 N ,则存储芯片的容量为 。

常见的存储扩展包括三种:位扩展、字扩展、字位扩展:
- 位扩展:扩展字长
- 字扩展:扩展字数
- 字位扩展:同时扩展字长和字数

补充
主存扩展方式和交叉编址方式有什么关系
总结为如下:
位扩展 采用 低位交叉编址 方案
位扩展采用低位交叉编址方案并扩展了计算机的字长
采用低位交叉编址方案并不一定要扩展计算机的字长
字扩展 采用 高位连续编址 方案
字位扩展 采用 低位和高位连续编址 方案的结合
位扩展
该图能更好的表现位扩展的 特性


记住: 位扩展是多个平面 结合的,结合 字位扩展 进行理解
字扩展

注意: 中高位地址线 可以留做后续的扩容用,不一定要都连在片选信号线上
CPU 地址线
按照位扩展的路数来看,字扩展 在 CPU 的地址线应该要变成 倍,但是研究上面字扩展图发现 CPU 的地址线位数没有改变?
实际上,因为主存的字数一般都是非常大的,在设计 CPU 和主存时,为了避免线路过多占据芯片面积,采用了很多手段以减少线数,例如:片选信号线
字位扩展

片选中的 位扩展芯片 组中,多个芯片中的第一行结合为 ”新的行“,称其为 一个存储单元
片选方法


总结
对于 DRAM 来说,可以没有片选线,因为它自带的 行列复用的 两个控制信号 可以起到选中一个芯片的功能; 但是 SRAM 只能老老实实用一位片选线
假设 要选中某一芯片组
表示选中 列;
表示选中 行;
可以令其他 DRAM 组的行列复用信号都变为
,表示未选中
这样就能表示哪一个芯片组被选中
Quote
做题总结
一般题目会给出一个 地址范围 等价于让你自己求出 这个 多体存储器的 地址引脚个数,即 存储字数
外存
硬盘
机械硬盘(磁盘存储器)
中优先级
偶尔会在大题中考察,在选择题中一般都会有一题,优先掌握 CHS 地址和 性能指标 的计算。
机械硬盘(Hard Disk Drive, HDD)是一种使用磁性存储介质来存储和读取数据的非易失性存储设备,广泛应用于计算机和数据存储系统中。
存储区域
为了理解机械硬盘是如何存储数据的,需要理解如下概念:
-
磁头(Heads):磁头是位于硬盘驱动器的读/写臂上的设备,用于读取和写入磁盘上的数据。每个盘片(硬盘通常包含多个盘片,每个盘片都有两个表面)上都有一个磁头,因此每个磁头都可以读取或写入盘片上的数据。磁头通过移动到不同的 磁道(track) 来寻找并访问数据。
-
Track(磁道):磁道是磁盘上的一个同心圆环。
-
Cylinders(柱面):柱面是硬盘上的一个数据存储区域,由相同半径位置上的多个盘片上的磁道组成。换句话说,它是所有盘片上相同半径位置的磁道的集合。
-
Sectors(扇区):扇区是磁盘上的最小数据存储单元。磁盘通常被划分成许多扇区,每个扇区可以存储一定数量的数据。扇区的大小通常是 512 字节 或 4KB。操作系统和磁盘控制器使用 扇区作为数据的最小单元 ,以读取和写入数据。

CHS 地址
当磁盘驱动器访问磁盘中的扇区时,需要根据 CHS 地址(Cylinder-Head-Sector Address,柱面 - 磁头 - 扇区地址) 定位到特定的扇区。
CHS 地址可以理解为盘块在磁盘中的编号,它通过以下三个字段来唯一标识磁盘上的一个扇区:
-
柱面号(Cylinder Number):目标扇区在哪一个柱面上
-
磁头号:目标扇区在哪一个盘面上
-
扇区号:目标扇区具体是磁道中的哪一个扇区
提示
一个磁盘有多个盘片,每个盘片有两个盘面,单个盘面对应一个磁头,每个盘面包含多个磁道和多个扇区,开始读取数据时,磁头从某个磁道和扇区的交叉位置开始扫描。
示例
假设一个磁盘有 1000 个柱面、4 个盘面、32 个扇区/磁道:
- 柱面号位数: ⌈log2(1000)⌉≈⌈9.97⌉=10 位
- 磁头号位数: ⌈log2(4)⌉=2 位
- 扇区号位数: ⌈log2(32)⌉=5 位
- CHS 地址总位数: 10+2+5=7 位
通过 CHS 地址(例如,C=500, H=2, S=15),磁盘驱动器可以精确定位到特定扇区。
性能指标
平均存取时间
平均存取时间是磁盘完成一次读写操作的平均耗时,由 寻道时间(Seek Time)、旋转延迟(Rotational Latency)和 传输时间(Read/Write Time)这三部分构成:
- 寻道时间:磁头从当前位置移动到目标磁道所需的时间,通常与磁头移动距离和致动器性能有关。
- 旋转延迟:盘片旋转使目标扇区到达磁头下方所需的时间,通常为盘片旋转半圈的平均时间,取决于转速。
- 传输时间:读取或写入目标扇区数据的实际时间,与扇区大小和数据传输率相关。

平均存取时间的计算公式为:

旋转延迟 默认都是算 转半圈需要的时间

本题没有给出 计算 传输时间 的因子,但是默认


数据传输率
数据传输率 表示磁盘每秒向主机传输数据的字节数,反映硬盘的读写速度。假设磁盘转速为 转/秒,每条磁道容量为 字节,则数据传输率 为:
总结

磁盘 格式化后的 实际容量 要比 非格式化后的 小,因为格式化过程里,在扇区中写入了一些控制信号,扇区尾部还留了一定的空隙。
RAID 校验
低优先级
从 2009 到现在就考过 1 题,而且各种 RAID 的细节太多,建议直接跳过。
RAID 全称为 独立磁盘冗余阵列(Redundant Arrar of Independent Disks)
由于磁盘存储介质数据的可靠性容易受到环境影响,而发生数据错误的代价非常大,因此需要考虑存储的容灾与恢复。

RAID 将多个独立的物理磁盘组成一个独立的逻辑盘,数据在多个物理盘上分割交叉存储、并行访问,具有更好的存储性能、可靠性和安全性。
RAID 的实现涉及以下核心技术:
- 磁盘镜像:将相同数据写入多块磁盘,提高可靠性。典型如 RAID1。
- 条带化:将数据分段交叉存储在多个磁盘上,提升性能。典型如 RAID0,但不具备容错能力。
- 奇偶校验:通过冗余校验位在部分磁盘损坏时重建数据,兼顾可靠性与存储效率。用于 RAID3/5/6。
- Cache 机制:提高读写性能,但本身不增加可靠性,除非使用掉电保护的写缓存。
常见 RAID 等级如 RAID1(镜像)、RAID5(条带化 + 奇偶校验)、**RAID6(双重奇偶校验)等在性能与容错能力之间做出不同权衡。
固态硬盘

固态硬盘(Solid State Drive, SSD)是一种使用闪存(NAND Flash)作为存储介质的非易失性存储设备,与传统机械硬盘(HDD)相比,SSD 在性能、耐用性和能效等方面具有显著优势。SSD 具备以下特点:
- 无机械部件:SSD 没有旋转盘片、磁头或机械臂等移动部件,它使用闪存存储芯片来存储数据。这意味着它不会受到机械故障的威胁,具有更高的耐用性。
- 更快的读写速度:SSD 的读写速度远远超过传统的机械硬盘,因为数据可以立即访问,无需等待盘片旋转和磁头寻道。这使得计算机启动更快,应用程序响应更迅速。
- 低访问时间:由于 没有机械延迟,SSD 的访问时间极低,通常在微秒级别。这有助于加快文件读取和数据检索。
- 长寿命:虽然每个存储单元有写入次数的限制,但现代 SSD 使用错误检查和纠正(ECC)技术,以延长其寿命,并且通常拥有较长的保修期。
- 无碎片化:SSD 的数据存储方式基于闪存单元,读取速度不受数据物理位置的影响,因此不会像 HDD 那样因数据碎片化而降低性能。
- 局限性:
- 容量限制:SSD 的高容量型号(例如 4TB 以上)价格昂贵,而 HDD 在大容量存储上更具优势。
- 写入寿命有限:尽管现代技术已大幅延长寿命,但重度写入场景下仍需关注寿命问题。
机械和固态硬盘对比

cache
Cache的诞生
- 性能飞跃:虽然 Cache 只占存储容量的不到 1%,但由于局部性,它能承载 CPU 约 90% 以上的访问请求(即高命中率)。这让整个存储器系统在用户看来,既拥有 Cache 的速度,又拥有内存的容量。
空间局部性(Spatial Locality)
-
现象:程序访问了一个位置,大概率马上会访问它邻近的位置(比如循环处理数组,或者顺序执行指令)。
-
好处:Cache 每次不是只搬一个字节,而是搬一整块(Cache Line)。因为空间局部性,这“一捆”数据里剩下的部分很快就会被用到,从而减少了去内存“进货”的次数。
时间局部性(Temporal Locality)
-
现象:被访问过的数据,大概率很快会被再次访问(比如循环变量
i,或者递归调用)。 -
好处:把刚用过的数据留在 Cache 里。因为时间局部性,下次再用时直接从 Cache 取,绕过了漫长的内存访问周期。
cache 存储结构
cache 存储的内容大体上来说可以分为 数据 和 元数据 这两个部分:
- 数据部分:即 cache 块(cache block),缓存了某个主存块的内容
- 元数据部分:对 cache 访问的过程进行控制
一般我们称 元数据就是 标记阵列
cache 的存储结构可以理解为一张表:

注意
cache 的存储结构依照具体的题目,在某些题目中 脏位、访问位 不用考虑,如果需要计算 cache 的容量,需要注意这一点。
其中字段的含义与 页表 近似,下面列出了:
-
有效位(valid):
- 该 cache 行 是否存储有缓存数据,位数为 1 位。
-
标记(tag):
- 根据物理地址中的 tag 字段与该字段匹配,以判断是否命中,位数按照 cache 地址结构 进行计算。
-
脏位(dirty):
-
访问位(reference):
- 用于记录访问信息,服务于 替换算法,其位数取决于替换算法。
- 如果采用 LRU 替换算法,则 访问位 的位数为 log2(主存快对应的缓存块数量) 。
-
数据块(block):
- 缓存的数据块,为 主存块 的一个副本。

先过 cache 再经过 cpu , 根据局部性原理,如果 cache 中没有当前块,则从主存中取货,将其放在对应空闲块,或使用替换算法,替换对应块。
映射方式

从抽象角度看,映射本质上定义了三件事:
- 可放置性:
一个主存块,允许放入 Cache 的哪些位置? - 唯一性或灵活性:
是只能放到一个固定位置,还是可以放到多个位置,甚至任意位置? - 硬件代价与性能权衡:
放得越自由,命中率越高,但查找与比较逻辑越复杂; 放得越受限,硬件越简单,但冲突失效(conflict miss)越频繁。
不同的映射方式,本质上就是在 命中率、访问速度、硬件复杂度 三者之间做不同取舍
直接映射

在 直接映射(directed mapped)缓存 中,每个 主存块 只能映射到缓存中的 一个特定缓存块。这意味着每个 主存块只有一个缓存块可以存储它。
主存块号 k 映射到缓存块号的计算公式为:
其中:
- k 为主存块号(从 0 开始编号),
- M 为缓存中的总块数。
全相联映射

在 全相联缓存(full associative)中,主存 中的任何块可以映射到缓存中的 任意缓存块。
其映射关系可表示为:
或更形式化地描述为:
其中 为缓存总行数。
由于这种映射关系不是唯一的,而是任意的,所以在根据物理地址去访问 cache 的时候,需要通过 遍历所有 cache 行 来判断是否命中。
如果 cache 的所有行都是满的,新的数据会根据某种 替换策略 来替换 cache 中的某一个 cache 块。
组相联映射

组相联缓存(set associative 或 group associative)是 直接映射缓存 和 全相联缓存 之间的一种 折中方案。它将缓存块分为多个 组,每个组包含多个缓存块。主存块可以 映射到组中的任意一个缓存块。
当我们说一个缓存是 N 路组相连 的,意味着缓存被分为多个 组,每个 组 有 N 个 缓存块(N 路)。这样,当一个内存地址被映射到一个特定的组时,它可以放在该 组的任何一个缓冲块(一路)上。
如果一个组是满的,新的数据会根据某种 替换策略 来替换组中的一个 缓存块。
组相联映射例子
假设我们有一个 256KB 的 缓存,其中每个 缓存块 是 64B,我们希望有 4 路组相联的组织。
- 这意味着 缓存 被分为
256KB / 64B = 4096个 缓存块。- 因为是 4 路组相联,所以这些块被进一步组织为
4096 / 4 = 1024个 组。- 每个 组 包含 4 个位置(即 4 路),任何内存地址映射到这个 组 的时候,可以放在这四个位置中的任何一个。
- 比如第 10000 个 主存块 位于第
10000 % 1024 = 784个 组,可能对应组内的任何一个 缓存块。
注意
N 路组相联 表示一个 组中有 N 个 cache 块,而不是 cache 中一共有 N 个组。
不然为啥不叫 N 组相联 呢?
组数与单个缓存块大小 以及 几路组 相关.
硬件结构

访问时,物理地址中的 组号(index) 用于定位到 Cache 中的某一 组。该 组 包含两个 Cache 块,每个块有 valid 位 和 tag 字段。
地址中的 tag 会同时送入两个 比较器,分别与组内两个块的 tag 进行匹配,并结合 valid 位 判断是否命中。
如果命中,选择器(multiplexer)根据比较结果,从两个块中选出正确的数据输出给处理器。若都未命中,则访问 主存。
比较器 与 选择器 的作用
- 比较器(Comparator):只有 组相联映射 时会用到,用于判断 Cache 块 中的 tag 是否与当前地址匹配,决定是否命中; 个数等于 组相联路数
- 选择器(Multiplexer):在多个块中有可能命中的情况下,负责根据比较结果选出正确的数据路径。
关联度
Cache 关联度(associativity)描述的是一块 主存地址 可以被映射到 缓存 中多少个不同的位置(cache lines)。
根据上面提及的 映射方式对比 可知关联度对比:
全相联 > 组相联 > 直接映射
更高的关联度意味着 缓存冲突 减少,命中率 提高。但是另一方面,硬件开销(比较器、替换策略复杂度)和访问延迟增加。所以关联度选择需权衡性能与成本。
映射方式对比
假设 cache 有 M 个 cache 块,对于块号为 k 的 主存块:
- 直接映射:被映射到块号
k % M的 cache 块 - 全相连映射:可能被映射到任意一个 cache 块
- 组相连映射:对于 m 路组相连,被映射到组号为
k % (M / m)的 cache 组 中的任意一个 cache 块


# 解题步骤参考
确定映射方式
利用条件确定 每个部分的 位数
特殊注意
此外, 题目中一般说的 cache 容量 说的都是数据阵列的大小,不算上标记阵列
否则,一个 Cache 行内还有其他标记位需要算上,数据对比一下不是 1:1
所以上面计算 位数的 公式中,缓存大小 单指 数据阵列
标记阵列 和 地址映射表 是一致的,即不算上 cache 行 上数据的 余下部分
注:一个 cache 中只有两个阵列,一个 标记(tag)阵列,还有一个就是 数据(data)阵列
区分概念
主存地址
存在 ,其构成 分别是 tag 和 行号加上一个 块内地址 (offset),但是实际 只有 tag 可能会和 cache 行搞混,因为这里的 tag 是用来 检验 行号 对应的 存储内容是否一致的
所以 会和 cache 行内容有一定交集
Cache 行
实打实存储在 cache 这个 由 SRAM 组成的 高速缓冲器中的
实在看不懂了对比一下图片 加深印象!!!

块内地址(offset)
这东西 是 cpu 需要 操心的事了,主存地址 里写它只是保持一个 地址指令 的 完整性
整体映射方式 以及计算 各部分位数时 ,都没有用它
cache 行号(行匹配字段)
这个玩意也是随 cache 映射方式 , 在硬件上进行改造的

牢记
组相联映射的 块匹配字段 是 ,理解上也比较容易,因为主存地址是用来找寻找 Cache 块的
标记位(tag)
位数等于:
物理地址对应

其中 块内偏移、cache 块号(直接映射)、cache 组号(组相联映射)的位数可以直接根据 cache 的参数计算出来,Tag 字段的位数需要通过物理地址的位数减去其他字段的位数来得到。
cache 中的替换
块替换算法适用于 全相联映射 和 组相联映射,因为在这两种组织方式中,同一主存块可能被 多个 cache 块 中的任意一个所缓存;因此当需要把新块写入时必须决定把哪一个已有的 cache 块淘汰。
而在 直接映射方式 中,主存块只能对应唯一的 一个 cache 块(即 选择 只有一个)
如果发生冲突 直接用新块覆盖该 cache 块即可,无需额外的替换算法
替换算法
当 CPU 访问某个物理地址而在 cache 中未命中时,需要把该地址所在的 主存块 调入 cache。如果该 主存块 映射到的 cache 块(即同一路径或同一个集合)已经全部占满,就必须在这些已占用的 cache 块 中挑选一个进行替换。常用的替换策略有 FIFO(先进先出)、LRU(最近最少使用)和 LFU(最不经常使用)等。
这套思路与操作系统中的页面置换算法本质相同,详情请参见 页面置换算法。
替换对比

cache 写策略
因为 cache 实际上存储的是主存的一个小副本,所以对于写操作,就需要考虑两者间的数据一致性的问题。
cache 的写策略代表当我们对某个物理地址上的数据进行写入时,应该如何写入对应的存储单元,以及如何协调 cache 和 主存之间的 数据一致性,写策略按照地址查询是否命中 cache 可以分为四种方式。
命中时

- 直写法(Write Through):
- 每次写操作都会同时更新缓存和主存。
- 这种写策略是 同步的,每次更新 缓存 时要同步地更新 主存。

- 回写法(Write Back):
- 当数据被修改时,它首先被缓存在 cache 中,只有当 cache 块被替换时才写入对应的主存块。
- 这种写策略是异步的,并不是写入 cache 后立马就要写入主存,可以多次写入 cache 后在另一个时刻再将cache 块写入主存。
注意
如果使用了回写法的话,就需要在 cache 中设置一个 脏位 。脏位用于记录这个 cache 块是否被写入过,如果被写入过,当这个 cache 块被替换时, 就需要写入到主存中。
可以看到,这种策略将多次 cache 写入合并为一个主存写入,对于写操作比较频繁的场景,其实很大幅度地提升了效率。
未命中时

- 写分配法(Write Allocate):
- 物理地址对应主存块被 加载 到 cache 块中(先执行一次对应主存块的读操作),然后更新 cache 块

既然这次只是要改数据,而我手里又没拿这块数据,那我就不去费劲把它搬进 Cache 了
适用于大规模初始化或写后不用的数据
- 非写分配法(Not Write Allocate):
- 不加载 主存块至 cache 中,直接更新主存块,只有当执行读操作时才将主存块加载进入 cache 块
策略的组合
命中 和 未命中 的方法常常通过如下方式一起使用:
- 直写法(write-through)和 非写分配法(not-write-allocate)通常会一起使用,适用于那些写操作不频繁或者写操作不太可能访问同一数据的情况。
- 回写法(write-back)和 写分配法(write-allocate)通常会一起使用,适用于那些写操作频繁的情况。

提示
方法的组合方式很容易被混淆,可以通过如下方式记忆:
- 直写法 和 非写分配法 都倾向于 主存 操作(写入 主存)。
- 回写法 和 写分配法 都倾向于 cache 操作(写入 cache)。
题目
改编前的映射题


本题主要矛盾点是对组相联映射的分组问题上,目前王道书上给出的解释是主存块依次放入不同分组;但是这里的说法是将 k 个主存块一次性填满一个组
虚拟存储器
高优先级
虚拟存储器 和 cache 一样重要,而且考察的方式往往是复合考察,将两者的知识融合在一起放到大题中考察,需要能够从存储系统全局看待这两者的关联。
虚拟存储器 是一种 计算机内存管理技术,它在 物理内存 和 磁盘存储 之间创建了一个抽象的、扩展的内存空间,以提供更大的可用内存容量。
设计核心 在于将 逻辑地址空间 与 物理内存 进行 解耦。程序在 编译和运行 时所看到的是一个连续、完整的虚拟地址空间,而实际上这些地址并不直接对应物理内存中的位置,而是通过 页表和TLB 进行映射。
物理内存
物理内存(Physical Memory)指的是计算机系统中的实际硬件内存,即随机存取存储器(RAM)。
物理内存 是计算机直接用于存储和操作数据的地方,所有进程的数据和代码实际上都是存储在 物理内存 上。
当访问物理内存时,必须使用 物理地址,物理地址就是 物理内存 中每个存储单元的唯一编号

虚拟内存
虚拟内存(Virtual Memory)是一种计算机系统内存管理技术,它使得进程可以认为自己拥有一个 连续且独立的内存空间,即使实际上 物理内存 可能不够用或者是分散的。
进程使用 虚拟地址 来访问内存中的数据和指令,而不需要了解 物理内存 的详细情况。进程使用虚拟地址去访问 虚拟内存,
当进程访问 虚拟内存 时,操作系统 会将 虚拟地址 转化为物理地址, 进而根据物理地址去访问 物理内存。

页式虚拟存储器
为了更灵活地管理内存,操作系统采用 页式虚拟存储器 的方式,将 虚拟地址空间 和 物理地址空间 都划分为大小固定的 页(Page)。
程序运行时,并不需要将整个虚拟地址空间都加载到 物理内存 中,而是 按需 将部分 页面载入内存,其余的页面保存在硬盘上。

当 CPU 发出一条内存访问指令时,地址转换机构 会找到对应的物理页框。如果发现该页面尚未加载到内存,就会触发 缺页中断。
缺页中断交由操作系统内核处理,内核会判断该页面是否在磁盘的交换区或程序映像文件中,如果存在,就将其调入内存。如果内存已满,还需要根据 页面置换算法(如最近最少使用 LRU 或时钟算法)选择一个合适的页面换出到磁盘,再将新页面调入。整个过程对应用程序是透明的,它只会感知到一次访问延迟,而不会意识到内存与磁盘之间的交换。
这种机制不仅让 有限的物理内存 可以支持 更大规模的虚拟地址空间,还实现了多进程之间的 隔离与保护。每个进程都有自己的页表,彼此之间的虚拟地址不会直接冲突,从而避免了进程间的非法访问。
同时,页式虚拟存储器还为实现内存共享提供了可能,比如多个进程可以将不同的虚拟页映射到同一个物理页框,用于共享代码段或数据。
简化过程
- 中有个进程 说 要一个内存单元, 通过总线发给 一个虚拟地址
- 先在 里头翻下(大概是没调入的)此处用的是 查找
- 到 Page Walk一下,若 页表显示 对应的 页面 在主存中,通过 到 主存中 寻找数据
- 若 页表 显示 该页面不在 主存中,执行缺页中断
注意
- 页表显示命中,先去 里找,再到主存中查找,随后将页面调入到 中
- 页表没中,相当于从 读指令 跳转到 写指令 了,写完之后记得回到读指令
先转地址再找数,TLB 没中查页目;
物理地址手中拿,Cache 没中找主存;
页表不在此谓“缺”,调回内存重起步。
页面划分和地址结构
在 页式虚拟存储器 中,虚拟内存空间 被划分为一个个 虚拟页面(VP,Virtual Page),物理内存空间 被划分为一个个 物理页面(PP,Physical Page)。
虚拟地址(VA, Virutal Address)被划分为 虚拟页面号(VPN,Virutal Page Number)和 页内偏移(Offset)这两个字段。
在使用 虚拟地址 去访问 虚拟内存 时,我们可以根据 虚拟页面号 找到该地址所在的 虚拟页面,在找到 虚拟页面 后,我们可以根据 页内偏移 找到该地址在 虚拟页面 内的偏移大小。

同理,物理地址(PA, Physical Address)被划分为 物理页面号(PPN,Physical Page Number)和 页内偏移(Offset)这两个字段。
在使用 物理地址 去访问 物理内存 时,我们可以根据 物理页面号 找到该地址所在的 物理页面,在找到 物理页面 后,我们可以根据 页内偏移 找到该地址在 物理页面 内的偏移大小。
注意
需要注意和区分一下以下几个名词,它们具有相同的含义:
虚拟页面(Virutal Page)= 逻辑页面(Logical Page)
页框(Frame) = 物理页面(Physical Page)
地址翻译机构

CPU 中的 内存管理单元(Memory Management Unit,MMU)是计算机体系结构的重要组成部分,它负责 虚拟内存 到 物理内存 的地址映射和内存访问的控制。MMU 的主要功能包括:
- 地址转换:MMU 负责将程序使用的 虚拟地址 转换为对应的 物理地址。
- 地址保护:MMU 实施内存保护策略,以确保不同的程序或进程无法越界访问彼此的内存空间。
- 内存访问权限:MMU 根据地址映射和保护位(在页表或段表中定义)来控制内存访问权限,包括读、写、执行等。
地址翻译是硬件还是软件完成的?
很多同学会困惑: 页表是操作系统维护的,而地址翻译要查页表;但 MMU 又是硬件结构,那地址翻译到底是硬件还是软件完成的?
关键点在于:操作系统“提供规则和数据”,硬件“执行翻译过程”。
首先,页表并不是操作系统可以随意设计的数据结构。 页表的层级、每一项的位含义(如有效位、权限位、物理页号等),都由 CPU 架构规范(如 x86、ARM)严格定义。操作系统只是按照该规范,在内存中构造符合格式要求的页表。
其次,真正的地址翻译过程由硬件完成。 CPU 中的 MMU(Memory Management Unit) 在执行指令时,会自动根据当前页表基址寄存器(如 CR3),按架构规定的流程遍历页表(或通过 TLB 命中),将虚拟地址转换为物理地址。 这个过程对软件是透明的,不需要操作系统逐条参与。
因此可以总结为:
页表的创建与维护:由操作系统负责(软件)
地址翻译的执行:由 MMU 完成(硬件)
页表(慢表)
页表(page table)是操作系统维护的一张表,用于将 虚拟地址 转化为 物理地址,每个运行的进程都有自己 页表。
重点
进程的 页表 存储在其 内存空间 中的 内核空间 中,详见进程内存空间。
在进程执行时,MMU 使用正在活动进程 对应的 页表 进行地址转换。
单级页表
对于 单级页表 而言,只需访问一次 页表 即可实现 页面号 的翻译过程。
虚拟地址: 虚页号 + 页内地址
解题思路
先算 页内地址位数, 其 由页面大小决定;
令 虚拟地址位数 减去 映射方式的匹配位 和 页内地址位数,得到 ;
对照给出的 页表 可以查找到 ,具体能不能用只要看 有效位是否置 就行
假如页表中 没有 对应的 则产生缺页中断, 如果进程中驻留集已满还需对换页面; 关键点:对换到内存的页面 其 物理地址 是原替换页面的 .
单级页表结构
一个典型的 单级页表 结构如下图所示:

页表 中的每一行叫做 页表项(PTE, page table entry),页表项 可包含如下内容:
-
虚拟页号(VPN,Virtual Page Number):对于 单级页表 而言,VPN 并不需要实际存储在 页表 的字段中,其隐性地作为 页表项 的下标进行存储。
-
物理页框号(PPN,Physical Page Number):当前 VPN 所对应的 物理页号。
-
有效位(Valid Bit):用于指示虚拟页 是否有效。若为 1,表示可用于地址转换;若为 0,表示无效,会导致错误。
-
修改位(Dirty Bit):用于指示虚拟页的内容 是否已被修改。若为 1,可能需要写回到磁盘或其他非易失性存储介质。
-
访问位(Accessed Bit):用于指示虚拟页 是否已被访问。若为 1,对页面置换算法有帮助。
-
保护位(Protection Bits):用于指定虚拟页的 访问权限,例如读取、写入或执行权限。
-
缓存位(Caching Bits):用于指示是否允许将虚拟页的内容 缓存在高速缓存中。
页表存储在物理内存中:
页表(无论是单级还是多级)最终都是一些数据结构,它们必须存储在物理内存(RAM) 中,CPU的内存管理单元(MMU) 才能直接读取它们进行地址转换。

多级页表
单级页表会有什么问题?
在 单级页表 中,为了管理大型 虚拟地址空间,需要创建庞大的 页表,其中包含大量 页表项,这会导致 页表 本身占用大量内存。
假如我们有一个 32 位 4GB 的 虚拟地址空间、4KB 的页面和一个 4 字节 的 PTE,那么我们将需要一个 4 MB 的 页面表 始终驻留在内存中,即使应用程序只引用 虚拟地址空间 的一小块。
多级页表结构

在 多级页表 中,虚拟页号(VPN)被分割为多个字段,假设被分割为 k 个字段的话,第 k 个字段对应的页表中的查询内容为 PPN,前 k‑1 个字段对应的页表中的查询内容为下一级页表的位置。
如果当前 多级页表 对应的一级页表有 mk 个 PTE,将 VPN 分割为 k 个长度相同的子字段后,每个子字段对应的页表的 PTE 个数为 logkmk=m 。
其中,第一层有 m 个页表,第二层最多有 m2 个页表在内存中存在, ⋯ ,第 k 层最多有 mk 个页表在内存中存在。
多级页表是如何节省内存的?

只有一级页表需要始终在主存中,对于其他层次的页表,可以 按需分配;如果使用到的,就在内存中创建对应的页表结构,如果未使用到,就不需要为其分配内存。这代表了巨大的潜在节省,因为典型程序的 4GB 虚拟地址空间 中的大部分都是未分配的。
对于 k 级页表而言,前 k‑1 级页表中 PTE 存储的关键字段都是下一级页表的位置,如果其中某个 PTE 的 有效位 为 0,那么操作系统无需为该 页表项 对应的下一级页表分配内存空间。
进程切换和页表管理
MMU 进行地址翻译的时候需要使用到页表,但是每个进程的页表不同,MMU 怎么知道当前进程的页表在物理内存的哪个位置呢?
其实操作系统是这样管理不同进程的页表的:

- 每个进程都有一个关键的内核数据结构,通常叫做 PCB 进程控制块。
- PCB 中保存了一个关键信息:页表基址寄存器 应该加载的物理地址。这个物理地址指向该进程 顶级页表 在物理内存中的起始位置。
- 当操作系统进行进程 上下文切换 时,它会:
- 保存当前进程的CPU状态到其PCB。
- 将下一个进程的PCB中保存的页表基址物理地址加载到CR3寄存器中。
- 恢复下一个进程的CPU状态。
- 一旦页表基址存储器被切换,MMU 接下来进行地址转换时,就会使用新进程的页表。这就是不同进程拥有不同虚拟地址空间映射的根本机制。
⭐PTBR
PTBR(Page Table Base Register,页表基址寄存器) 是处理器中用于 指向当前进程顶级页表物理地址 的专用寄存器。
- 它保存的是 页表在物理内存中的起始地址,而不是虚拟地址
- MMU 在进行地址翻译时,会 从 PTBR 出发逐级查页表
- 每个进程都有自己的页表,但同一时刻只有一个 PTBR 生效
PTBR 决定了“当前 CPU 看到的是哪一个进程的虚拟地址空间”

与进程切换的关系:
- 进程切换 = 切换 PTBR
- 操作系统在上下文切换时,把新进程页表的物理地址加载进 PTBR(如 CR3)
- 之后 MMU 的所有地址翻译都会基于新进程的页表
TLB(快表)
TLB(Translation Lookaside Buffer)是 CPU 内存管理单元(MMU)中的一种 高速缓存,用于加速 虚拟地址(VA)到 物理地址(PA)的地址转换过程。TLB 存储了最近用过的 虚拟地址 到 物理地址 的映射,以减少每次内存访问时的地址翻译延迟。

由于 页表 存储在内存中,所以每一次通过 页表 的地址翻译过程都至少需要一次访存,开销仍然比较大。为降低开销,TLB 应运而生。与 Cache 类似,你可以从概念上将 TLB 理解成一个硬件结构,因离 CPU 更近,其访问速度更快。
存储结构
*TLB 是一个硬件结构,但从逻辑上可以将其理解为一张表。

与 cache 存储结构 类似,TLB 由许多 表项(TLB Entry)构成,每一个 表项 包含多个字段,其中 tag 和 PPN 是必须的,其他字段是可选的。
TLB 和 cache 对比
TLB 和 页表 的关系类似于 cache 与 主存 的关系,TLB 和 cache 都是硬件结构,只是作用场景不同。TLB 与 Cache 的区别如下表所示:

TLB 中也包含三种映射方式:直接映射、全相联映射、组相联映射。
在访问 TLB 时,虚拟地址 中的 虚拟页号(VPN)被按照映射方式进行不同的切分。在访问 cache 时,物理地址 中的 主存块号 被按照映射方式进行不同的切分。
两者的对比如下所示:

在 直接映射 中,通过 TLB 行号去对应行的 表项 进行查询。
在 组相联映射 中,通过 TLB 组号去对应组进行查询(遍历组中的所有 TLB 表项)。
在 全相联映射 中,遍历 TLB 中的所有 表项。
地址结构
当我们通过 TLB 进行 虚拟页号(VPN)→ 物理页号(PPN) 的翻译时,访问 TLB 需要使用到 VPN。
从逻辑上而言,VPN 可以被分为 标记 和 匹配字段 这两个部分:
- 标记(TLBT, 即 TLB Tag):与 TLB 中的 tag 进行对比,判断是否命中 TLB 表项。
- 匹配字段(Match Field),通过该字段判断 VPN 可能被哪些 TLB 表项所缓存,这里 TLB 与 Cache 类似,同样具有三种映射方式,每一种映射方式的 匹配字段 位数不同:
- 直接映射:匹配字段为 TLB 表项编号,即行编号(TLB entry index),其位数为 log2(TLB 行数)
- 全相联映射:没有匹配字段,即匹配字段位数为 0,因为每一个 VPN 都可能被任何一个 TLB 行所缓存
- 组相联映射:匹配字段为组号(TLB group index),位数为 log2(TLB 组数)

使用 TLB 进行地址翻译的过程如下:
- 给定一个 虚拟地址(VA),从中提取出 虚拟页号(VPN)
- 根据映射方式从 VPN 中提取出 标记(TLBT)和 匹配字段
- 根据 匹配字段 从 TLB 的相应表项中依次查找,命中时应满足如下条件:
- 有效位(valid)为 1
- 该表项中的 TLBT 与 VPN 中的 tag 字段相同
- 若命中某个表项,则通过 TLB 完成 VPN → PPN 的翻译
- 若未命中,则通过 页表 完成翻译
| 对比维度 | 基本分页管理的进程 | 请求分页管理的进程(虚拟内存) |
|---|---|---|
| 启动门槛 | 高。 必须把进程的全部页面一次性装入内存,少一页都不能启动。 | 低。 启动时只需装入几个初始页面(比如 main 函数所在的页),进程就能开始跑。 |
| 进程大小限制 | 进程的总大小不能超过物理内存的剩余空间。 | 进程的总大小可以远大于物理内存(比如 8GB 内存跑 20GB 的游戏)。 |
| 页表项的内容 | 页表项很简单,通常只记录: 1. 页号 2. 物理块号 | 页表项更复杂,除了物理块号,还必须包含: 1. 状态位(存在位):标记这一页是否在内存中 2. 修改位(脏位):标记这一页在内存中是否被修改过 3. 访问位、外存地址等 |
请求分页管理
请求分页管理(Demand Paging)是一种计算机操作系统中的内存管理技术,它允许进程在需要时才将 页面(或者说 虚拟内存 中的数据块)加载到 物理内存 中,而不是一次性将整个进程加载到内存中(基本分页):
- 进程开始运行时,并 不把所有页装入内存
- 访问到某一页时才触发:
- 缺页异常(page fault)
- 从磁盘调入该页
- 是一种 懒加载(lazy loading)
注意
我们平时说“页式虚拟存储”,默认指的基本都是 “请求页式管理”。与请求方式相对应的,叫做基本分页机制,也就是说:
在进程运行前,提前装入一部分或全部页面。
但是在考研语境和实践中,都是指的是请求页式管理。
页面错误
当进程尝试访问一个 虚拟页面,但该页面当前未加载到 物理内存 中时,会触发 页面错误(page fault)。此时,操作系统会将相应的页面从磁盘加载到 物理内存,进行 页面替换
当然,上述说法中沿用了教材中的叙述方式:
缺页 → 从磁盘调入 → 进行页面替换
这是一个 简化模型。
实际上,page fault 的本质 是:
CPU 访问虚拟地址
页表项 valid = 0 触发异常
由内核修复映射
至于修复方式:
- 建立映射
- 分配物理页
- 读磁盘
都可能
如何判断访问的页面是否在物理内存中呢?
通过查询 TLB 和 页表(见 单级页表)以判断某个 虚拟地址 对应的页面是否在内存中。
从 虚拟地址(VA)中提取出 虚拟页号(VPN),再查询 TLB 和 页表 中是否存在包含 VPN 的记录。如果都不存在,则说明内存中不存在与 VPN 对应的 物理页面。
Caution
提问? 计算机通过什么 找到 外存上对应的 缺失页,又是怎么调入到主存中的
页表项是“双面人”:Valid=1 时它是内存地址,Valid=0 时它是磁盘索引;OS 负责根据这个索引把数据从工厂(磁盘)搬运到仓库(内存)。
页面替换
页面替换 时包含两种情况:
- 物理内存 中存在 空闲页面(未被任何进程使用的页面)。
- 进程 中不存在任何 空闲页面,即所有页面都被进程使用了。

如果存在 空闲页面,当一个进程出现 缺页中断 时,直接使用 空闲页面 即可。
如果 物理内存 已满,操作系统需要选择一个页面来替换。通常,操作系统会选择一个 不再需要的页面 进行替换,这个决策基于 使用的页面置换算法。
如果操作系统中配置了 交换分区(swap area),被置换的页面会被写入 交换分区;当该页面再次被需要时,页面会从 交换分区 中加载回 物理内存。
交换页面

交换分区 是硬盘上专门划出的一个区域,用来作为系统内存的“扩展”。当 物理内存 使用接近或达到上限时,操作系统会把暂时不用的内存页(比如不活跃的后台程序)移到 交换分区,从而释放出 物理内存。
访存过程
对于进程而言,它自己可见的就是 虚拟地址(VA),当进程访问 虚拟地址 时,实际上是对某个 物理地址 进行访问。

访存 主要包含两大过程:
- 地址翻译:VPN → PPN,即由 虚拟地址(VA)得到 物理地址(PA)的过程。
- 根据 物理地址(PA)去 cache 或 主存 中读取数据。
需要熟练掌握这两大过程中的各种细节,考试中常将这些知识点组合考察。
虚拟地址翻译过程
操作系统经过如下步骤将 虚拟地址 转为 物理地址:
- 从 虚拟地址(VA)中提取 VPN(虚拟页号)。
- 根据 VPN 去访问 TLB。
- 命中 TLB:从 TLB 中读取相应的 物理页号(PPN)。
- 未命中 TLB:读取 页表 后更新 TLB。
- 命中页表:从 页表 中读取相应的 PPN,并更新 TLB 表项。
- 未命中页表:触发 缺页中断,从内存中找一个页面以加载 物理页面
- 存在 空闲页面,直接使用 空闲页面,使用其 PPN 更新 页表。
- 不存在 空闲页面,选择一个进程的页面进行置换。
- 组装 物理页号(PPN)和 页内偏移(PPO)得到 物理地址。
物理地址访存过程
访存 过程常与 地址翻译 过程一起考察。进程访问一个 虚拟地址 时,首先完成 地址翻译 得到 物理地址,随后使用该 物理地址 访问内存。
使用 物理地址 访问内存时首先判断是否命中 cache;若未命中,则访问 内存,随后更新 cache。在使用 主存块 更新 cache 块 的过程中,还要根据 cache 与 主存 的映射方式决定替换哪个 cache 块,详细过程如下图所示。

虚拟地址翻译和访存过程总结
如果将 地址翻译过程 与 访存过程 放在一起,一个 虚拟地址 访问内存的大致流程为:

补充总结
段式虚拟存储器 以及 段页式虚拟存储器 没有在 笔记中写,
这部分留到操作系统中记录, 段页式 虚存 大题考到概率极低, 但是 需要 理解其中 段式和 页式 结合的 思想


为啥呢?
错题
虚页号的理解
一般情况下,虚页号作为下标是不存储在页表中的,所以给出的数值一般都是十进制
本题的核心处理,将得到的 进制 虚页号 转换到 十进制,再和页表对照
虚存概念
TLB 映射




