01.存储管理
存储器的层次化结构
计算机存储设备可被粗略分为内存储器(Main Memory)与外存储器(External Memory)两大类,内存存取速度快,但容量小,价格昂贵,而且不能长期保存数据,在不通电情况下数据会消失;外存储器存取速度相对较慢,却可以吃持久化存储。如果进行更加细致地划分,每个计算机系统中的存储设备都被组织成了一个存储器层次结构,在这个层次结构中,从上至下,设备变得访问速度越来越慢、容量越来越大,并且每字节的造价也越来越便宜。
最上层的是寄存器,存取时间极快,但容量小。其次是高速缓存,存取时间次之,容量比寄存器大一些。再往下就是我们常见的内存、硬盘,存取速度递减,但容量越来越大。CPU 在访问数据时,数据一般在相邻两层之间复制传送,且总是从慢速存储器复制到快速存储器,通过这种方式保证 CPU 的速度和存储器的速度相匹配。寄存器的存取时间在 1ns 级别,存储容量小于 1KB,可看做就是 L1 的高速缓存。L1 等高速缓存的存取时间在 2ns 级别,存储容量为 4MB;L1 是 L2 的高速缓存,L2 是 L3 的高速缓存,L3 是主存的高速缓存。主存的存取时间在 10ns 级别,存储容量目前在 GB 级别;主存又是磁盘的高速缓存。磁盘的存取速度在 10ms 级别,存储容量可达 TB 级别,在某些具有分布式文件系统的网络系统中,本地磁盘就是存储在其他系统中磁盘上的数据的高速缓存。
CPU 仅可以直接从位于处理器芯片上的高速缓存中直接获取指令和数据。必须从主系统内存(随机存取内存或 RAM)中加载缓存。但是,RAM 仅在通电时才保留其内容,因此需要存储在更永久的存储器中。
Speed | Memory | Description |
---|---|---|
Fastest | Cache | 高速缓存是实际上嵌入在 CPU 内部的内存。高速缓存内存非常快,通常只需要访问一个周期,但是由于它直接嵌入到 CPU 中,因此内存大小是有限制的。实际上,高速缓存有几个子级别(称为 L1,L2,L3),它们的速度都略有提高 |
RAM | 处理器的所有指令和存储地址都必须来自 RAM。尽管 RAM 速度非常快,但是 CPU 仍需要花费大量时间来访问它(称为latency)。RAM 存储在与主板相连的单独的专用芯片中,这意味着它比高速缓存大得多 | |
Slowest | Disk | 我们都熟悉软盘或 CDROM 上的软件,并将文件保存到硬盘上。我们还熟悉程序从硬盘加载所需的长时间-具有诸如旋转磁盘和移动磁头之类的物理机制意味着磁盘是最慢的存储形式。但它们也是迄今为止最大的存储形式 |
了解内存层次结构的重点是速度和大小之间的权衡-内存越快,内存越小:
- 空间局部性(Spatial locality)表明,块内的数据可能会一起访问。
- 时间位置(Temporal locality)表明最近使用的数据可能很快会再次使用。
这意味着,通过在实际中尽可能快地实现存储相关信息(空间)小块的快速可访问存储器(时间),可以获得好处。
主存
主存是一个临时存储设备,在处理器执行程序时,用来存放程序和程序处理的数据。从物理上来说,主存是由一组动态随机存取存储器(DRAM)芯片组成的。从逻辑上来说,存储器是一个线性的字节数组,每个字节都有其唯一的地址(即数组索引),这些地址是从零开始的。一般来说,组成程序的每条机器指令都由不同数量的字节构成。
现代 DRAM 的结构和存取原理比较复杂,这里抽象出一个十分简单的存取模型来说明 DRAM 的工作原理。从抽象角度看,主存是一系列的存储单元组成的矩阵,每个存储单元存储固定大小的数据。每个存储单元有唯一的地址,现代主存的编址规则比较复杂,这里将其简化成一个二维地址:通过一个行地址和一个列地址可以唯一定位到一个存储单元。
当系统需要读取主存时,则将地址信号放到地址总线上传给主存,主存读到地址信号后,解析信号并定位到指定存储单元,然后将此存储单元数据放到数据总线上,供其它部件读取。写主存的过程类似,系统将要写入单元地址和数据分别放在地址总线和数据总线上,主存读取两个总线的内容,做相应的写操作。这里可以看出,主存存取的时间仅与存取次数呈线性关系,因为不存在机械操作,两次存取的数据的“距离”不会对时间有任何影响,例如,先取 A0 再取 A1 和先取 A0 再取 D3 的时间消耗是一样的。
寄存器与高速缓存
寄存器文件在层次结构中位于最顶部,也就是第 0 级或记为 L0。一个典型的寄存器文件只存储几百字节的信息,而主存里可存放几十亿字节。然而,处理器从寄存器文件中读数据的速度比从主存中读取几乎要快 100 倍。针对这种处理器与主存之间的差异,系统设计者采用了更小、更快的存储设备,即高速缓存存储器(简称高速缓存),作为暂时的集结区域,用来存放处理器近期可能会需要的信息。
L1 和 L2 高速缓存是用一种叫做静态随机访问存储器(SRAM)的硬件技术实现的。比较新的、处理能力更强大的系统甚至有三级高速缓存:L1、L2 和 L3。系统可以获得一个很大的存储器,同时访问速度也很快,原因是利用了高速缓存的局部性原理,即程序具有访问局部区域里的数据和代码的趋势。通过让高速缓存里存放可能经常访问的数据的方法,大部分的存储器操作都能在快速的高速缓存中完成。
块设备与磁盘
块设备将信息存储在固定大小的块中,每个块都有自己的地址。对操作系统而言,块设备是以字符设备的外观展现的,例如 /dev/sda,虽然对这种字符设备可以按照字节为单位访问,但是实际上到块设备上却是以块为单位(最小 512byte,即一个扇区),这之间的转换是由操作系统来实现的。下面介绍几个块设备的基本概念:
-
扇区:磁盘盘片上的扇形区域,逻辑化数据,方便管理磁盘空间,是硬件设备数据传送的基本单位,一般 512Byte;
-
块:块是 VFS 和文件系统数据传送的基本单位,必须是扇区的整数倍,格式化文件系统时,可以指定块大小(一般 512,1024,2048,4096 字节);
-
段:一个内存页或者内存页中的一部分,包含一些相邻磁盘扇区中的数据;磁盘的每个 IO 操作就是在磁盘与一些 RAM 单元之间相互传一些相邻扇区的内容,大多数情况下,磁盘控制器采用 DMA 方式进行数据传送。如果不同的段在 RAM 中相应的页框是连续的并且在磁盘上相应的数据块也是相邻的,就可以在通用块层合并它们,产生更大的内存区域,这个区域称为物理段。
通常情况下,我们是通过文件系统来访问块设备,也可以直接使用裸设备,通过指定偏移和大小来读写裸设备。常见的块存储设备就是物理磁盘,磁盘是一种直接存取的存储设备 (DASD);它是以存取时间变化不大为特征的。可以直接存取任何字符组,且容量大、速度较其它外存设备更快。在 Linux 系统下,还提供基于其他块设备之上的逻辑设备,如 Device Mapper,软 RAID 等。