存储器层次结构

  • 存储器系统是一个具有不同容量、成本和访问时间的存储设备的层次结构。CPU寄存器保存着最常用的数据。靠近CPU的小的、快速的高速缓存存储器是一个缓冲区,缓存的是存储在相对慢速的主存储器中数据和指令的一部分。主存缓存存储在容量较大的、慢速磁盘上的数据,而这些磁盘常常又作为存储在通过网络连接的其他机器的磁盘或磁带上的数据的缓冲区域。
  • 如果你的程序需要的数据是存储在CPU寄存器中的,那么在指令的执行期间,在0个周期内就能访问到它们。如果存储在高速缓存中,需要$4 \sim 75$个周期。如果存储在主存中,需要上百个周期。而如果存储在磁盘上,需要大约几千万个周期。
  • 计算机系统中的一个基本而持久的思想:如果你理解了系统是如何将数据在存储器层次结构中上上下下移动的,那么你就可以编写自己的应用程序,使得它们的数据存储器在层次中较高的地方,在那里CPU能更快的访问到它们。
  • 这个思想围绕着计算机程序的一个称为局部性(locality)的基本属性。具有良好局部性的程序倾向于一次又一次地访问相同的数据项集合,或是倾向于访问邻近的数据项集合。

随机访问存储器

  • 随机访问存储器分为两类:静态的和动态的。静态RAM(SRAM)比动态RAM(DRAM)更快,但也贵得多。SRAM用来作为高速缓存存储器,既可以在CPU芯片上,也可以在片外。DRAM用来作为主存以及图形系统的帧缓冲区。

静态RAM

  • SRAM将每个位存储在一个双稳态的存储器单元里。每个单元是用一个六晶体管电路来实现的。这个电路有这样一个属性,它可以无限期地保持在两个不同的电压配置或状态之一。
  • 由于SRAM存储器单元的双稳态特性,只要有电,它就会永远地保持它的值。即使有干扰(例如电子噪音)来扰乱电压,当干扰消失时,电路就会恢复到稳定值。

动态RAM

  • DRAM将每个位存储为对一个电容的充电。DRAM存储器可以制造得非常密集——每个单位由一个电容和一个访问晶体管组成。但是,于SRAM不同,DRAM存储器单元对干扰非常敏感。当电容的电压被扰乱之后,它就永远不会恢复了。

传统的DRAM

  • DRAM芯片中的单元(位)被分成d个超单元(supercell),每个超单元都由wDRAM单元组成。一个$d × w$的DRAM总共存储了dw位信息。
  • 每个DRAM芯片被连接到某个称为内存控制器的电路,这个电路可以一次传送w位到每个DRAM芯片或一次从每个DRAM芯片传出w位。

内存模块

  • DRAM芯片封装在内存模块中,它插到主板的扩展槽上。

非易失性存储器

  • 如果断电,DRAMSRAM会丢失它们的信息,从这个意义上说,它们是易失的。另一方面,非易失性存储器即使在关电后,仍然保存着它们的信息。现在有很多种非易失性存储器。由于历史原因,虽然ROM中有的类型既可以读也可以写,但是他们整体上都被称为只读存储器。
    • PROM只能被编程一次。PROM的每个存储器单元有一种熔丝,只能用高电流熔断一次。
    • 可擦写可编程ROM时可擦写可编程ROM
    • 闪存是一类非易失性存储器,基于EPPROM,它已经成为了一种重要的存储技术。
  • 存储在ROM设备中的程序通常被称为固件。当一个计算机系统通电以后,它会运行存储在ROM中的固件。

访问主存

  • 数据流通过称为总线的共享电子电路在处理器和DRAM主存之间来来回回。每次CPU和主存之间的数据传送都是通过一系列步骤来完成的,这些步骤称为总线事务。读事务从主存传送数据到CPU,写事务从CPU传送数据到主存。
  • 总线是一组并行的导线,能携带地址、数据和控制信号。取决于总线的设计,数据和地址信号可以共享同一组导线,也可以使用不同的。同时,两个以上的设备也能共享同一总线。控制线携带的信号会同步事务,并标识出当前正在被执行的事务的类型。

磁盘存储

  • 磁盘是广为应用的保存大量数据的存储设备,存储设备的数量级可以达到几百到几千千兆字节,而基于RAM的存储器只能有几百或几千兆字节。

固态硬盘

  • 固态硬盘是一种基于闪存的存储技术。
  • 注意,读SSD比写要快。随机读和写的性能差别是由底层闪存基本属性决定的。一个闪存由B个块的序列组成,每个块由P页组成。通常,页的大小是512字节~4KB,块是由$32 \sim 128$页组成的,块的大小为$16KB \sim 512KB$。数据是以页为单位读写的。只有在这一页所属的块整个被擦除之后,才能写这一页。不过,一旦一个块被擦出了,块中每一个页都可以不需要在进行擦除就写一次。
  • 随机写很慢,有两个原因。首先,擦除块需要相对较长的时间,1ms级的,比访问页所需时间要高一个数量级。其次,如果写操作试图修改一个包含已经有数据的页p,那么这个块种所有带有用数据的页都必须被复制到一个新(擦除过的块),然后才能进行对页p的写。

存储技术趋势

  • 增加密度比降低访问时间容易得多
  • SRAM的性能滞后于CPU的性能,但还是在保持增长。不过,DRAM和磁盘性能与CPU性能之间的差距实际上是在加大的。
  • 现代计算机频繁地使用基于SRAM的高速缓存,试图弥补处理器-内存之间的差距。这种方法行之有效是因为应用程序的一个称为局部性的基本属性。

局部性

  • 一个编写良好的计算机程序通常具有良好的局部性。也就是,它们倾向于引用邻近于其他最近引用过的数据项的数据项。或者最近引用过的数据项本身。这种倾向性,被称为局部性原理,是一个持久的概念,对硬件和软件系统的设计和性能都有极大的影响。
  • 局部性通常有两种不同的形式:时间局部性和空间局部性。在一个具有良好时间局部性的程序种,被引用过一次的内存位置很可能在不远的将来再被多次引用。在一个具有良好空间局部性的程序中,如果一个内存位置被引用了一次,那么程序很可能再不远的将来引用附件的一个内存位置。

局部性小结

  • 重复引用相同变量的程序有良好的时间局部性
  • 对于具有步长为k的引用模式的程序,步长越小,空间局部性越好。具有步长为1的引用模式的程序有很好的空间局部性。在内存中以大步长跳来跳去的程序空间局部性会很差
  • 对于取指令来说,循环有好的时间和空间局部性。循环体越小,循环迭代次数越多,局部性越好。

存储器层次结构

  • 存储技术:不同存储技术的访问时间差异很大。速度较快的技术每字节的成本要比速度较慢的技术高,而且容量较小。CPU和主存之间的速度差距在增大。
  • 计算机软件:一个编写良好的程序倾向于展示出良好的局部性
  • 存储器层次结构
    • 一般而言,从高层往底层走,存储设备变得更慢、更便宜和更大。再最高层(L0),是少量快速的CPU寄存器,CPU可以在一个时钟周期内访问它们。接下来是一个或多个小型到中型的基于SRAM的高速缓存存储器,可以在几个CPU时钟周期内访问它们。然后是一个大的基于DRAM的主存,可以在几十到几百个时钟周期内访问它们。接下来是慢速但是容量很大的本地硬盘。最后,有些系统甚至包括了一层附加的远程服务器上的磁盘,要通过网络来访问它们。

存储器层次结构中的缓存

  • 一般而言,高速缓存是一个小而快速的存储设备,他作为存储在更大、也更慢的设备中的数据对象的缓冲区域。使用高速缓存的过程称为缓存。
  • 存储器层次结构的中心思想是:对于每个k,位于k层的更快更小的存储折别作为位于k+1层的更大更慢的存储设备的缓存。
    • 存储器层次结构中缓存的一般性概念。第k+1层的存储器被划分成连续的数据对象组块,称为块。每个块都有一个唯一的地址或名字,使之区别于其他的块。块可以是固定大小的,也可以是可变大小的。
    • 类似的,第k层的存储器被划分成较少的块的集合,每个块的大小与k+1层的块的大小一样。在任何时刻,第k层的缓存包含第k+1层块的一个子集的副本。
    • 数据总是以块大小为传送单元在第k层和第k+1层之间来回复制的。

缓存命中

  • 当程序需要第k+1层的某个数据对象d时,它首先在当前存储在第k层的一个块种查找d。如果d刚好缓存在第k层中,那么就是我们所说的缓存命中。该程序直接从第k层读取d,根据存储器层次结构的性质,这要比从第k+1层读取d更快。

缓存不命中

  • 另一方面,如果第k中没有缓存数据对象d,那么就是我们说的缓存不命中。当发生缓存不命中时,第k层的缓存从第k+1层缓存中取出包含d的那个块,如果第k层的缓存已经满了,可能就会覆盖现存的一个块。
  • 覆盖一个现存的块的过程称为替换或驱逐这个块。被驱逐的这个块有时也称为牺牲块。决定该替换哪个块是由缓存的的替换策略来控制的。

缓存不命中的种类

  • 区分不同种类的缓存不命中有时候是很有帮助的。如果第k层的缓存是空的,那么对任何数据对象的访问都会不命中。一个空的缓存有时被称为冷缓存,此类不命中被称为强制性不命中或冷不命中。
  • 只要发生了不命中,第k层的缓存就必须执行某个放置策略,确定把它从第k+1层中取出的块放在哪里。最灵活的放置策略是允许来自第k+1层的任何块放在第k层的任何块中。这个策略实现起来通常很昂贵,因为随机的放置块,定位起来代价很高。
  • 因此,硬件缓存通常使用的是更严格的放置策略,这个策略将第k+1层的某个块放限制放置在第k层块的一个小的子集中。
  • 这种限制性的放置策略会引起一种不命中,称为冲突不命中,在这种情况中,缓存足够大,能够保存被引用的数据对象,但是因为这些对象会映射到同一个缓存块,缓存会一直不命中。
  • 程序通常是按照一系列阶段来运行的,每个阶段访问缓存块的某个相对稳定不变的集合。这个快的集合称为这个阶段的工作集。当工作集的大小超过缓存的大小时,缓存会经历容量不命中。换句话说就是,缓存太小了,不能处理这个工作集。

缓存管理

  • 存储器层次结构的本质是,每一层存储折别都是较低一层的缓存。在每一层上,某种形式的逻辑必须管理缓存。这里,我们的意思是指某个东西要将缓存划分成块,在不同的层之间传送块,判定是命中还是不命中,并处理它们。管理缓存的逻辑可以是硬件、软件,或是两者的结合。

存储器层次结构概念小结

  • 概括来说,基于缓存的存储器层次结构行之有效,是因为较慢的存储设备比较快的存储设备更便宜,还因为程序倾向于展示局部性:
    • 利用时间局部性:由于时间局部性,同一数据对象可能会被多次使用。一旦一个数据对象在第一次不命中时被复制到缓存中,我们就会期望后面对该目标有一系列的访问命中。
    • 利用空间局部性:块通常包含有多个数据对象。由于空间局部性,我们会期望后面对该块中其他对象的访问能够补偿不命中后复制该块的花费。

高速缓存存储器

  • 早期计算机系统的存储器层次结构只有三层:CPU寄存器、DRAM主存储器和磁盘存储。不过,由于CPU和主存之间逐渐增大的差距,系统设计者被迫在CPU寄存器文件和主存之间插入了一个小的SRAM高速缓存存储器,称为L1高速缓存。L1高速缓存的访问速度几乎和寄存器一样快,典型地大约4个时钟周期。
  • 随着CPU和主存之间地性能差距不断增大,系统设计者在L1高速缓存和主存之间又插入了一个更大的高速缓存,称为L2高速缓存,可以在大约10个时钟周期内访问到它。有些现代系统还包括一个更大的高速缓存,称为L3高速缓存,在存储器层次结构中,它位于L2高速缓存和主存之间,可以在大约50个周期内访问到它。