5. Memory Hierarchy
硬盘、内存、CPU 寄存器,还有本节要讲的 Cache,这些都是存储器,计算机为什么要有这么多种存储器呢?这些存储器各自有什么特点?这是本节要讨论的问题。
由于硬件技术的限制,我们可以制造出容量很小但很快的存储器,也可以制造出容量很大但很慢的存储器,但不可能两边的好处都占着,不可能制造出访问速度又快容量又大的存储器。因此,现代计算机都把存储器分成若干级,称为 Memory Hierarchy,按照离 CPU 由近到远的顺序依次是 CPU 寄存器、Cache、内存、硬盘,越靠近 CPU 的存储器容量越小但访问速度越快,下图给出了各种存储器的容量和访问速度的典型值。
图 17.8. Memory Hierarchy

表 17.1. Memory Hierarchy
| 存储器类型 | 位于哪里 | 存储容量 | 半导体工艺 | 访问时间 | 如何访问 |
|---|---|---|---|---|---|
| CPU 寄存器 | 位于 CPU 执行单元中。 | CPU 寄存器通常只有几个到几十个,每个寄存器的容量取决于 CPU 的字长,所以一共只有几十到几百字节。 | “寄存器”这个名字就是一种数字电路的名字,它由一组触发器(Flip-flop)组成,每个触发器保存一个 Bit 的数据,可以做存取和移位等操作。计算机掉电时寄存器中保存的数据会丢失。 | 寄存器是访问速度最快的存储器,典型的访问时间是几纳秒。 | 使用哪个寄存器,如何使用寄存器,这些都是由指令决定的。 |
| Cache | 和 MMU 一样位于 CPU 核中。 | Cache 通常分为几级,最典型的是如上图所示的两级 Cache,一级 Cache 更靠近 CPU 执行单元,二级 Cache 更靠近物理内存,通常一级 Cache 有几十到几百 KB,二级 Cache 有几百 KB 到几 MB。 | Cache 和内存都是由 RAM(Random Access Memory)组成的,可以根据地址随机访问,计算机掉电时 RAM 中保存的数据会丢失。不同的是,Cache 通常由 SRAM(Static RAM,静态 RAM)组成,而内存通常由 DRAM(Dynamic RAM,动态 RAM)组成。DRAM 电路比 SRAM 简单,存储容量可以做得更大,但 DRAM 的访问速度比 SRAM 慢。 | 典型的访问时间是几十纳秒。 | Cache 缓存最近访问过的内存数据,由于 Cache 的访问速度是内存的几十倍,所以有效利用 Cache 可以大大提高计算机的整体性能。一级 Cache 是这样工作的:CPU 执行单元要访问内存时首先发出 VA,Cache 利用 VA 查找相应的数据有没有被缓存,如果 Cache 中有就不需要访问物理内存了,如果是读操作就直接将 Cache 中的数据传给 CPU 寄存器,如果是写操作就直接改写到 Cache 中;如果 Cache 没有缓存该数据,就去物理内存中取数据,但并不是要哪个字节就取哪个字节,而是把相邻的几十个字节都取上来缓存着,以备下次用到,这称为一个 Cache Line,典型的 Cache Line 大小是 32~256 字节。如果计算机还配置了二级缓存,则在访问物理内存之前先用 PA 去二级缓存中查找。一级缓存是用 VA 寻址的,二级缓存是用 PA 寻址的,这是它们的区别。Cache 所做的工作是由硬件自动完成的,而不是像寄存器一样由指令决定先做什么后做什么。 |
| 内存 | 位于 CPU 外的芯片,与 CPU 通过地址和数据总线相连。 | 典型的存储容量是几百 MB 到几 GB。 | 由 DRAM 组成,详见上面关于 Cache 的说明。 | 典型的访问时间是几百纳秒。 | 内存是通过地址来访问的,在启用 MMU 的情况下,程序指令中的地址是 VA,而访问内存用的是 PA,它们之间的映射关系由操作系统维护。 |
| 硬盘 | 位于设备总线上,并不直接和 CPU 相连,CPU 通过设备总线的控制器访问硬盘。 | 典型的存储容量是几百 GB 到几 TB。 | 硬盘由磁性介质和磁头组成,访问硬盘时存在机械运动,磁头要移动,磁性介质要旋转,机械运动的速度很难提高到电子的速度,所以访问速度很受限制。保存在硬盘上的数据掉电后不会丢失。 | 典型的访问时间是几毫秒,是寄存器访问时间的 106 倍。 | 由驱动程序操作设备总线控制器去访问。由于硬盘的访问速度较慢,操作系统通常一次从硬盘上读几个页面到内存中缓存起来,如果这几个页面后来都被程序访问到了,那么这一次读硬盘的时间就可以分摊(Amortize)给程序的多次访问了。 |
对这个表格总结如下。
- 寄存器、Cache 和内存中的数据都是掉电丢失的,这称为易失性存储器(Volatile Memory),与之相对的,硬盘是一种非易失性存储器(Non-volatile Memory)。
- 除了访问寄存器由程序指令直接控制之外,访问其它存储器都不是由指令直接控制的,有些是硬件自动完成的,有些是操作系统配合硬件完成的。
- Cache 从内存取数据时会预取一个 Cache Line 缓存起来,操作系统从硬盘读数据时会预读几个页面缓存起来,都是希望这些数据以后会被程序访问到。大多数程序的行为都具有局部性(Locality)的特点:它们会花费大量的时间反复执行一小段代码(例如循环),或者反复访问一个很小的地址范围中的数据(例如访问一个数组)。所以预读缓存的办法是很有效的:CPU 取一条指令,我把和它相邻的指令也都缓存起来,CPU 很可能马上就会取到;CPU 访问一个数据,我把和它相邻的数据也都缓存起来,CPU 很可能马上就会访问到。设想有两台计算机,一台有 256KB 的 Cache,另一台没有 Cache,两台计算机的内存都是 512MB 的,硬盘都是 100GB 的,虽然多出来 256KB 的 Cache 与内存、硬盘的容量相比微不足道,但访问 Cache 比访问内存、硬盘快几个数量级,由于局部性原理,CPU 大部分时间是在和 Cache 打交道,有 Cache 的计算机明显会快很多。高速存储器的容量只能做得很小,却能显著提升计算机的性能,这就是 Memory Hierarchy 的意义所在。