千里之行始于足下

CSAPP阅读笔记(3)-存储器层次结构

Posted on By Peter Yang

原来总把memory理解为内存,在这里是不合适的,还是称为存储器更具有一般性。存储器是计算机体系结构中不可或缺的一部分,在冯-诺依曼结构中是必要的组成部分。PC中常见的存储器有寄存器,高速缓存(即CPU上的Cache),主存(即常说的内存)以及磁盘。另外,也有人把远端机器的存储介质也算在内。这样,就形成了存储器的层次结构,如下图所示。

这张图中划分中更为细致,共分了六级,从0到5。从上到下依次是寄存器,L1 cache,L2 cache,主存,磁盘,远端存储介质。这张图呈现了存储器的金字塔型构造。左侧的箭头表明,处于金字塔高端的存储器具有较高的访问速度以及较贵的价格,而处于金字塔低端的存储器具有较低的访问速度以及较便宜的价格。在这两个因素的平衡下,在单个系统中,高级存储器容量一般较小,而低级存储器容量较大。

下表是各级存储器的访问速度。

</div>

</tr> </tbody> </table> </div> </div> </div> 由上表可以看出,前面几级的速度基本差不多,差距最大的是磁盘,其速度与前面差了N个数量级。这是存储器层次结构必须存在的原因之一。 下面从其本质来看。寄存器与CPU紧密相连,在此不讨论。从高速缓存到主存都属于随机访问存储器(Random-Access Memory, RAM)。RAM分为两类,静态RAM(SRAM)和动态RAM(DRAM)。这里的静态和动态之分,是看存储内容是否需要动态刷新。在通电情况下,SRAM不用刷新,而DRAM需要以某种策略来刷新数据。( 有意思的是,其内部刚好相反,由于SRAM中采用触发器来存储,其内部一直有电流流动,故实际上是动态的,而DRAM采用电容来存储,故实际上是静态的。从这个意义上来说,SRAM比DRAM耗能要多)DRAM不断的发展变化,产生新的产品,我就不一一举例了。从我开始使用电脑时,只见过SDRAM以及后来的DDR了。SDRAM的S表示Synchronous,即同步。该技术比它的先趋所采用的异步技术,在访问速度上有了提高。DDR,全称Double Data-Rate Synchronous DRAM,即双倍速率的SDRAM。其利用时钟触发的上升沿和下降沿来访问数据,使其速率比SDRAM快了一倍。至于再往后的DDR2,DDR3除了升频之外,不知道还有没有结构上的变化。另外,显存与通常的主存还是不一样的。本来嘛,它的应用需求就不同。显卡要求显存具有更大的数据吞吐率,因此显存一般都支持并发的读/写操作。 前面讲述的RAM都属于易失性存储器,即数据的保持需要电源供应。下面介绍非易失性存储器。通常称为ROM(Read-Only Memory),字面译为只读存储器。由于历史原因一直沿用至今。现在的ROM不仅可读也可写。ROM常用于主板上的固存,用于存储BIOS以及开机自检等基本程序。后来发展有EPROM,称为可擦写ROM,实际上是光可擦写,一般可反复存储1000次左右。近来有EEPROM,即俗称的E平方PROM,称作电可擦写ROM。现在广泛使用的U盘就是采用这一存储技术。 再来看一下磁盘,其结构示意图如下所示。 上左图是单个盘片示意图,上右图是整个磁盘示意图。由于盘片是双面存储,故三个盘片就有六个表面,每个表面由一系列同心圆构成,一个同心圆称为一个磁道。一个磁道上分为多个扇区,每个扇区上存储固定容量的数据。此时,就会有一个问题,同心圆大小不一,因此,不同的磁道存储能力不同。一种方式是不管其大小,各磁道存储量相同,这样对于越靠近外边缘的磁道,存在的浪费越多(图中的gaps)。另一种方式,是将磁道按到圆心距离分组,同组的磁道存储量相同,这样有助于减少浪费,但同时提升了磁盘操作的复杂性。不管哪种方式,gaps是一定存在的。这些gaps可以利用来做些冗余备份机制以提高存储的可靠性(当然,这是较高级的磁盘才有的特性)。 关于磁盘转速,在这里废话一下呵。PC机常用5400RPM和7200RPM,笔记本常用5400RPM,这个速率似乎一直没有提升。服务器使用的磁盘可能会达到10000RPM或15000RPM,并且使用一些可靠性技术。 现在来考虑一下磁盘的访问速度。前面看到,磁盘访问的速度低了很多,最根本的原因是其依赖于数据读写机械臂的运动。机械运动的速度和电子运动的速度是不具备可比性的。磁盘访问时间一般由三部分组成,即寻道时间+磁轴旋转时间+数据传输时间。这三部分时间中,后两者对于同一磁盘而言,基本认为是常数,产生差异的主要是前者。不同的寻道方式消耗时间差距较大,因此就有各种各样的磁盘访问算法产生,主要就是针对这部分时间进行优化。由于磁盘的访问速率较慢,因此利用中断机制配合DMA(Direct Memory Access)机制在磁盘和主存中传输数据。 存储器层次结构(即缓存结构)存在的原因之二,是由于数据访问的时间和空间局部性原理,即数据访问在时间和空间上都趋于相同或相近的数据。但是时空特性的好坏因程序的不同而不同(人为写出时空特性狂差的程序还是很有可能地),所以必须要强调这一局部性原理。由于这一原理的存在,可将最近最常使用的数据或代码放在离CPU较近的缓存中,以提高访问速率。关于具体的编程需要注意的细节,还是即时查书的好,作为总结不必要了。 至于cache的结构,一般也是采用将地址分段的方法来检索。低位表示块内部寻址,中间表示选择索引,高位表示标签,用于在集合内部依序查找。其示意图如下所示。 在上图中,set index的定位可以一次性匹配,而在set内部,只能依据tag值进行匹配判断。多个tag存在的一个问题就是,当需要进行置换时,采用什么样的置换策略呢?在L1 Cache中,采用了直接映射缓存,即每个set中只包含一个tag。这避免了置换策略的问题,是为了简化设计,同时也是因为置换算法在那种级别的访问速度上效果不明显。一般的置换算法(如LRU等)多用于主存和磁盘这一级别。 这章内容蛮多的,不少东西没有概括到,但主线基本已经覆盖到。便于以后查找。
存储器类型</td> 访问速度(以时钟周期计)
寄存器 0
高速缓存 1~10
主存 50~100
磁盘 20,000,000
远端存储介质 ~=20,000,000