分类
- 按存取方式分类
- 随机存取存储器(RAM):访问任何一个存储单元所需时间基本相同,例如主存、Cache。
- 顺序存取存储器(SAM):必须按顺序找到位置,如磁带。
- 直接存取存储器(DAM):先大致定位,再在小范围内顺序找,如磁盘。
- 按内容寻址的存储器(相联存储器):根据内容而不是地址来访问,如 TLB、Cache 中的某些结构。
- 按存储介质分类
- 半导体存储器:主存、Cache、寄存器,多用 SRAM/DRAM。
- 磁表面存储器:硬盘、磁带。
- 光存储器:光盘(CD/DVD)。
- 按信息是否会因断电丢失分类
- 易失性存储器:断电后信息消失,如绝大多数 RAM(主存)。
- 非易失性存储器:断电信息仍在,如磁盘、SSD、ROM、Flash。
- 按读写性质分类
- 读写存储器(RWM):既可读又可写,如主存。
- 只读存储器(ROM):用户一般只能读,如程序固化在 ROM 中。
存储结构
典型的存储层次结构(从上到下):
- 寄存器(Register):
- 位于 CPU 内部,速度最快,容量最小,价格最高(按位算)。
- 保存正在参与运算的操作数、地址等。
- 高速缓存(Cache):
- 介于 CPU 与主存之间,利用程序的时间局部性和空间局部性。
- 速度接近寄存器,但容量比寄存器大一些,成本仍然较高。
- 主存(Main Memory,内存):
- 与 CPU 直接交换信息的主要存储器。
- 容量中等,速度中等,成本中等,是程序运行时的工作区。
- 辅助存储器(Secondary Storage):
- 包括磁盘、SSD、U 盘、光盘等。
- 容量最大、速度最慢、成本最低,多用于长期、大量信息的存放。
总体特点(自上而下):
- 速度:快 → 慢
- 容量:小 → 大
- 单位比特价格:高 → 低
主存基本结构
- 主存由大量存储单元(Storage Cell) 构成,每个单元有自己的唯一地址(Address)。
- 所有存储单元排成一维序列,可以编号为 0, 1, 2, …, N−1。
- 每个存储单元能存一定数量的比特,如 8 bit(1 Byte)、16 bit(1 个字),视系统而定。
- 还有两大存储器:
- MAR:用来存放要访问的主存单元的地址。
- MDR:用来存放要写入主存或从主存读取出来的数据。
CPU 与主存的一次典型读/写过程(简化版)
- 读(Read):
- CPU 把要访问的地址送入 MAR;
- CPU 发出“读控制信号”;
- 主存根据地址,将对应单元的数据送入 MDR;
- MDR 中的数据被送入 CPU 内部寄存器,供运算使用。
- 写(Write):
- CPU 把要写入的地址送入 MAR;
- CPU 把要写入的数据送入 MDR;
- CPU 发出“写控制信号”;
- 主存将 MDR 中的数据写入到由 MAR 指定的存储单元。
编址方式与主存容量的基本计算
编址方式:
- 字节编址:每个地址对应一个字节(8 bit)存储单元。地址 0、1、2、… 对应的是第 0、1、2、… 个字节。大多数通用计算机采用字节编址。
- 字编址:每个地址对应一个“字”,一个字可能是 16 bit、32 bit 或 64 bit。
地址线和数据线
地址线和存储单元数量
-
若 CPU 有 n 条地址线,则最多可表示 2ⁿ 个不同地址。
-
这 2ⁿ 个地址对应 2ⁿ 个存储单元(每个单元的大小由系统决定:1 Byte 或 1 个字等)。
数据线与存储字长 -
数据线的条数通常等于存储字长,一次并行能传输的数据位数。
-
例如有 32 条数据线,则一次可以传输 32 bit(4 Byte)的数据。
-
字(Word):计算机进行一次整数运算或传送时,CPU 作为一个整体处理的数据长度单位。
-
字长:一个“字”中所包含的二进制位数,即 CPU 一次能自然处理的位数。
- 16 位机:字长 = 16 bit(1 字 = 16 位)。
- 32 位机:字长 = 32 bit(1 字 = 32 位 = 4 Byte)。
- 64 位机:字长 = 64 bit(1 字 = 64 位 = 8 Byte)。
-
一台机器的字长通常等于:
- 通用寄存器的位数;
- ALU(算术逻辑单元)一次处理的位数;
- 数据总线宽度(一次可并行传输的位数,很多机器如此设计)。
所以:字长越大,CPU 处理整数运算的“天然精度”和一次处理能力就越强。
存储芯片及引脚
M * N 的含义:M:芯片中存储单元的个数,即“有多少个地址”。N:每个存储单元的位数(bit 数)。芯片总容量(按 bit 计)= M × N bit。
若芯片有 M 个存储单元,要区分这些单元需要满足:
M = 2ᵏ → 需要 k 根地址线。即地址引脚数 = log₂(存储单元个数)。
数据引脚数 = 每个存储单元的位数 N。例如 “1K×8” 芯片 → 8 根数据引脚(D0~D7)。
再加上一些控制引脚,比如:
- 片选 CS(Chip Select):决定这片芯片是否被“选中工作”。
- 读写控制引脚 OE/WE 或 RD/WR:决定是读操作还是写操作。
容量扩展
位扩展
目标:增加字长(位宽),即每个存储单元的位数变大,存储单元个数保持不变。
方法要点(概念层面):
- 多个芯片的地址引脚并联在一起 → 它们看到的是相同的地址。
- 多个芯片的数据引脚分别接到不同的数据线位上 → 合起来形成更宽的数据总线。
- 所有芯片的片选信号相同(同时选通),读写控制信号也相同。
| 目标 | 做法 | 结果规格示例 |
|---|---|---|
| 从 1K×8 → 1K×16 | 两片 1K×8 做位扩展并排 | 地址数仍 1K,每单元 16 位 |
字扩展
目标:增加存储单元个数(地址数量),即“字数/深度”变大,每个存储单元位数不变。
方法要点(概念层面):
- 各个芯片的数据引脚并联到同一数据总线(因为对应地址只会启用一片)。
- 各个芯片的地址引脚也并联接在地址线的低位上(它们管理“内部地址”)。
- 使用片选信号 CS来决定在同一时刻到底启用哪一片芯片:
- 通常用高位地址通过译码器产生片选信号。
| 目标 | 做法 | 结果规格示例 |
|---|---|---|
| 从 1K×8 → 2K×8 | 两片 1K×8 做字扩展,“上下叠加” | 地址数翻倍,每单元仍 8 位 |
| 从 1K×8 → 4K×8 | 四片 1K×8 字扩展,利用 2 位高地址译码 | 地址数变 4K,每单元仍 8 位 |
局部性原理(Cache为什么有用)
比喻:
- 时间局部性
- 如果你今天刚写过一道题,这道题很可能一会儿还要翻回来对答案,看解析,或者改错。
- 也就是“刚用过的东西,很快还会再用”。
- 空间局部性
- 你打开课本第 50 页看例题,通常接着会看 49、51 页的相关内容,而不是跳到第 300 页。
- 也就是“用到一个位置的数据,很可能还会用到它附近的数据”。
概念:
- 时间局部性(Temporal Locality)
- 含义:若某数据(或指令)在某时刻被访问,则在不久的将来它很可能再次被访问。
- 典型来源:循环、频繁调用的函数、被多次使用的变量。
- 空间局部性(Spatial Locality)
- 含义:若某个存储单元被访问,则其邻近的存储单元在不久时间内也有很大概率被访问。
- 典型来源:顺序执行的指令流、顺序访问的数组、结构体成员等。
- 与 Cache 的关系
- Cache 把主存划分成若干块(Block),一次从主存搬一整块到 Cache,利用空间局部性。
- 最近访问的块保留一段时间,利用时间局部性。
Cache 基本概念与性能指标
命中(Hit):要访问的数据在 Cache 中找到。
缺失(Miss):要访问的数据不在 Cache 中,需要从更低层(主存)调入。
命中率 h:h = \frac{\text{命中次数}}{\text{总访问次数}}
访问时间的基本定义
设:
- T_C:访问 Cache 所需时间(命中时,只用访问 Cache 的时间)。
- T_M:访问主存所需时间(缺失时,要访问主存的时间)。
[TODO] 如何计算
性能指标的直观理解
- h 越大(命中率越高),平均访问时间越接近 T_C,系统越快。
- 若 h 从 90% 提升到 95%,在主存比 Cache 慢很多的情况下,平均时间改善很明显。
- 有时题目会给你:
- Cache 命中率 = 95%
- Cache 访问时间 = 1 个周期
- 主存访问时间 = 10 个周期
然后让你算平均访问时间。