深入理解计算机系统-存储器层次结构(一)

        存储器系统是一个具有不同容量,成本和访问时间的存储设备的层次结构。 CPU寄存器保存着最常用的数据。靠近CPU的小的,快速的高速缓存器作为一部分存储在相对慢速的主存储器中数据和指令的缓冲区域主存缓存存储在内容较大的,慢速磁盘上的数据,而这些磁盘常常又作为存储在通过网络连接的其他机器的磁盘或磁带上的数据的缓冲区域

6.1 存储技术

6.1.1 随机访问存储器

        随机访问存储器(RAM)分为两类:静态的和动态的。静态RAM(SRAM)比动态RAM(DRAM)更快,但也贵得多。 SRAM是用来作为高速缓存存储器 ,既可以在CPU芯片上,也可以在芯片下。DRAM 用来作为主存以及图形系统的帧缓冲区。 典型的,一个桌面系统的SRAM不会超过几兆字节,但DRAM却有几百或几千兆字节。

        1. 静态 RAM

        SRAM 将每个位存储在一个双稳态的存储器单元里。每个单元是用一个六晶体管电路实现的。每个电路有这样一个属性:它可以无限期地保持在两个不同的电压配置或状态之一。其他任何状态都是不稳定的——从不稳定状态开始,电路会迅速地转移到两个稳定状态中的一个。这样的存储器单元类似于6-1的倒转的钟摆。ad18b1d959e24cc6b75626b5e5c86ca7.png

        当钟摆倾斜到最左边或最右边时,它是稳定的。从其他任何位置,钟摆都会倒向一边或另一边。原则上,它也能在垂直的位置无限期地保存平衡,但是这个状态是亚稳态的——最轻微的扰动也能使它倒下,而且倒下就不会再恢复到垂直的位置

        由于 SRAM 存储器单元的双稳态特性,只要有电,就会永远的保持它的值。即使有干扰来扰乱电压,当干扰消除时,电路就会恢复到稳定值。

        2. 动态RAM

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

        很多原因会导致漏电,使得 DRAM 单元在 10~100 毫秒时间内失去电荷。幸运的是,计算机运行的时钟周期是以纳秒衡量,所以相对而言这个保持时间是比较长的。 内存系统必须周期性地通过读出,然后重写来刷新内存每一位。有些系统也使用纠错码,其中计算机的字会被多编码几个位,这样,电路可以发现并纠正一个字中任何单个的错误位。0a6c7409d42a4e0dadb3388c275e5b69.png

        3. 传统的 DRAM

        DRAM 芯片中的单元(位)被分成 d 个超单元每个超单元都由 w 个 DRAM 单元组成。一个 d*w 的DRAM 总共存储了 dw 位信息。 这d个超单元被组织成一个 r 行 c 列 的长方形阵列,这里 r*c=d ,每个超单元有形如(i,j)的地址,这里 i 表示行,而 j表示列。

        例如,图 6-3 展示的是一个 16*8 的DRAM 芯片组织,有 d=16个超单元每个超单元有 w=8 位,r=4 行,c=4 列。 带阴影的方框表示地址(2,1)处的超单元。信息通过称为 引脚 的外部连接器流入和流出芯片每个引脚携带一个 1位的信号。 图 6-3 给出了两组引脚:8个 data 引脚,它们能传送一个字节到芯片从芯片传出一个字节,以及 2 个 addr 引脚,它携带 2 位的行和列超单元地址。其他携带控制信息的引脚没有显示出来。

41b29307d95d4dcab44d67558e487b76.png

         每个 DRAM 芯片被连接到某个称为内存控制器的电路,这个电路可以一次传送 w 位到每个 DRAM 芯片一次从每个 DRAM 芯片传出 w 位。 为了读出超单元(i,j)的内容,内存控制器将行地址 i 发送到 DRAM,然后是列地址 j。 DRAM 把超单元(i,j)的内容发回控制器作为响应。 行地址 i 称为 RAS 请求,列地址 j 称为 CAS 请求。 RAS和CAS请求共享相同的DRAM地址引脚

         例如,要从图 6-3 中 16*8 的 DRAM 中读出超单元(2,1),内存控制器发送行地址2,如图6-4a 所示。 DRAM 的响应是将行 2 的整个内容都复制到一个内部行缓冲区。接下来,内存控制器发送列地址 1,如图6-4b 所示。 DRAM的响应是从行缓冲区复制出超单元(2,1)中的8位,并把它们发送到内存控制器。 6e8061c1a466464084b384c801b2d677.png

         电路设计者将 DRAM 组织成二维阵列而不是线性数组的一个原因是降低芯片上地址引脚的数量。例如,如果示例的128位 DRAM 被组织成一个 16 个超单元的线性数组,地址为0~15,那么芯片会需要 4 个地址引脚 而不是两个。二维阵列组织的缺点是必须分两步发送地址,增加了访问时间。

        4. 内存模块

        DRAM 芯片封装在内存模块中,它插到主板的扩展槽上。Core i7 系统使用的240个引脚的双列直插内存模块,它以64位为块传送数据到内存控制器从内存控制器传出数据

        图 6-5 展示了一个内存模块的基本思想。示例模块用 8 个 64 Mbit 的 8M*8 的DRAM芯片,总共存储 64MB(兆字节),这八个芯片编号为 0~7。每个超单元存储主存的一个字节而用相应超单元地址为(i,j)的8个超单元来表示主存中字节地址A处的64位字。在图6-5 的示例中,DRAM 0 存储第一个(低位)字节,DRAM1存储下一个字节,以此类推。

        要取出内存地址A处的一个字,内存控制器将 A 转换成一个超单元地址(i,j),并将它发送到内存模块,然后内存模块再将 i 和 j 广播到每个 DRAM。作为响应,每个DRAM输出它的(i,j)超单元的 8 位内容。模块中的电路收集这些输出,并把它们合并成一个64位字,再返回给内存控制器

        通过将多个内存模块连接到内存控制器,能够聚合成主存。在这种情况中,当控制器收到一个地址A时,控制器选择包含A的模块k,将 A 转换成它的(i,j)的形式,并将(i,j)发送到模块k

881c1a3a132c4152a440a21ebf75adf0.png

 5.增强的DRAM

        每种增强的 DRAM 都是基于传统的DRAM单元,并进行一些优化,提高访问基本 DRAM 单元的速度。

        ① 快页模式DRAM(Fast Page Mode DRAM,FPM DRAM)。 传统的DRAM将超单元的一整行复制到它的内存缓冲区中,使用一个,然后丢弃剩余的。FPM DRAM 允许对同一行连续地访问 可以直接从行缓冲区得到服务,从而改进了这一点。例如,要从一个传统的DRAM的行 i 中读取 4 个超单元,内存控制器必须发送四个 RAS/CAS请求,即使是行地址 i 在每个情况中都是一样的。要从一个 FPM DRAM 的同一行中读取超单元,内存控制器发送第一个 RAS/CAS 请求,后面跟三个 CAS 请求。初始的 RAS/CAS 请求将行 i 复制到行缓冲区,并返回CAS 寻址的那个超单元,接下来三个超单元直接从行缓冲区获得,因此返回的比初始超单元更快。

        ② 扩展数据输出DRAM(Extend Data Out DRAM,EDO DRAM)。是 FPM DRAM 的一个增强形式,允许各个CAS 信号在时间上靠的更紧密一点。

        ③ 同步 DRAM(Synchronous DRAM,SDRAM)。就它们与内存控制器通信使用一组显示的控制信号来说,常规的,FPM和EDO DRAM都是异步的。SDRAM 用与驱动内存控制器相同的外部时钟信号的上升沿来代替许多这样的控制信号。最终效果是SDRAM能够比那些异步的存储器更快地输出它的超单元内容

        ④双倍数据速率同步DRAM(Double Data-Rate Synchronous DRAM,DDR SDRAM)DDR SDRAM 是对 SDRAM 的一种增强,它通过使用两个时钟沿作为控制信号,从而使 DRAM 的速度翻倍。 不同类型的DDR SDRAM是用提高有效带宽的很小的预取缓冲区的大小来划分的:DDR(2 位),DDR2(4位),DDR(8位)。

        ⑤ 视频RAM (Video RAM)。它用在图形系统的帧缓冲区。VRAM的思想与FPM DRAM 类似,两个主要区别:1)VRAM 的输出是通过依次对内部缓冲区的整个内容进行移位得到的。2)VRAM 允许对内存并行地读和写。因此,系统可以在下一次更新的新值(写)的同时,用帧缓冲区中的像素刷屏幕(读)

6. 非易失性存储器

        如果断点,DRAM和SRAM会丢失它们的信息,从这个意义上说,它们是易失的。另一方面,非易失性存储器即使是在关电后,仍然保存着它们的信息。虽然ROM中有的类型既可以读也可以写,但是整体上都被称为只读存储器(Read-Only Memory,ROM)。ROM是以它们能够被重编程(写)的次数和对它们进行重编程所用的机制区分的

        PROM(Programmable ROM,可编程ROM)只能被编程一次。PROM 的每个存储器单元有一种熔丝(fuse),只能用高压电流熔断一次

        可擦写可编程ROM(Erasable Programmable ROM,EPROM)有一个透明的石英窗口,允许光到达存储单元。紫外线光照射过窗口,EPROM 单元就被清除为 0. 对 EPROM 编程是通过使用一种把 1 写入 EPROM 的特殊设备来完成的。EPROM 能够被擦除和重编程的次数的数量级可以达到 1000 次电子可擦除 PROM(Electrically Erasable PROM,EEPROM) 类似于EPROM,但它不需要一个物理上独立的编程设备,因此可以直接在印制电路卡上编程。EEPROM能够被编程的次数的数量级可以达到10^5次

        闪存(flash memory)是一类非易失性存储器,基于EEPROM。闪存无处不在,为大量的电子设备提供快速而持久的非易失性存储(包括数码相机,手机,音乐播放器,笔记本,台式机和服务器计算机系统)在6.1.3节中,会研究新型的基于闪存的磁盘驱动器,称为固态硬盘(Solid State Disk,SSD),它能提供相对于传统旋转磁盘的一种更快速,强健和低能耗的选择。

         存储在 ROM 设备中的程序通常被称为固件(firmware)。当一个计算机系统通电以后,它会运行存储在ROM中的固件。一些系统在固件中提供了少量基本的输入和输出函数——例如PC的BIOS(基本输入/输出系统)例程。

7.访问主存

        数据流通过称为总线(bus)的共享电子电路在处理器和DRAM主存之间来来回回。每次CPU和主存之间的数据传送都是通过一系列步骤来完成的,这些步骤称为总线事务(bus transaction)读事务(read transaction)从主存传送数据到CPU写事务(write  transaction)从CPU传送数据到主存.

        总线是一组并行的导线,能携带地址,数据和控制信号.取决于总线的设计,数据和地址信号可以共享同一组导线,也可以使用不同的。同时,两个以上的设备也能共享同一总线。控制线携带的信号会同步事务,并标识出当前正在被执行的事务的类型。

        图 6-6 展示了一个实例计算机系统的配置。主要部件是CPU芯片,我们称为 I/O桥接器(I/O bridge)的芯片组(其中包括内存控制器),以及组成主存的DRAM 内存模块。 这些部件由一对总线连接起来,其中一条总线是系统总线(system bus),它连接CPU 和 I/O 桥接器,另一条总线是内存总线(memory bus),它连接I/O 桥接器和主存I/O桥接器将系统总线的电子信号翻译成内存总线的电子信号 I/O 桥也将系统总线和内存总线连接到 I/O 总线

f67a364efc0f47a78eac23d8833d42cf.png

        考虑当 CPU 执行一个如下加载操作时会发生什么:

        movq A,%rax

这里,地址A的内容被加载到寄存器 %rax中。CPU芯片上称为 总线接口(bus interface)的电路在总线上发起读事务。读事务是由三个步骤组成。首先,CPU 将地址A放到系统总线上I/O 桥将信号传递到内存总线(6-7a)。接下来,主存感觉到内存总线上的地址信号,从内存总线读地址,从DRAM取出数据字,并将数据写到内存总线。I/O桥将内存总线信号翻译成系统总线信号,然后沿着系统总线传递(6-7b)。最后,CPU感觉到系统总线上的数据,从总线上读数据,并将数据复制到寄存器%rax(6-7c)。

9e92d9249e024b0f81a9cf253be42e79.png

        反过来,当CPU执行一个像下面这样的存储操作时

        movq %rax,A

这里,寄存器%rax的内容被写到地址A,CPU发起写事务。同样,有三个基本步骤。首先,CPU将地址放到系统总线上,内存从内存总线读出地址,并等待数据到达(6-8a),接下来,CPU将%rax 中的数据字复制到系统总线(6-8b),最后,主存从内存总线读出数据字,并且将这些位存储到DRAM中(6-8c)

19c8781b11624b42a6fa62b74b1950d4.png

6.1.2  磁盘存储

        磁盘是广为应用的保存大量数据的存储设备,存储数据的数量级可以达到几百到几千 千兆字节,而基于RAM的存储器只能有几百或几千兆字节。不过,从磁盘上读信息的时间为毫秒级,比从DRAM读慢了10万倍,比从SRAM读慢了100万倍

        1.磁盘构造

        磁盘是由盘片构成的。每个盘片有两面或者称为表面(surface),表面覆盖着磁盘记录材料盘片中央有一个可以旋转的主轴,它使得盘片以固定的旋转速率旋转,通常是5400~15000转每分钟(Revolution Per Minute RPM)。磁盘通常包含一个或多个这样的盘片,并封装在一个密封的容器内。

        图6-9a 展示了一个典型的磁盘表面的结构。每个表面是由一组称为磁道(track)的同心圆组成的每个磁道被划分为一组扇区(sector)。每个扇区包含相等数量的数据位(通常是512字节),这些数据编码在扇区上的磁性材料中。扇区之间由一些间隙(gap)分隔开,这些间隙中不存在数据位。间隙存储用来标识扇区的格式化位。

        磁盘是由一个或多个叠放在一起的盘片组成的,它们被封装在一个密封的包装里,如6-9b所示,整个装置通常被称为磁盘驱动器(disk drive),我们通常简称磁盘(disk)。有时,会称磁盘为旋转磁盘(rotating disk),以之区别于基于闪存的固态硬盘(SSD),SSD是没有移动部分的

60610be0be744f2d8bc039af8732f88b.png

柱面是 所有盘片表明上到主轴中心的距离相等的磁道的集合(每个面的磁道数)。 

4e37c536d9fc41a3a1b3e3dffacf8b18.png

        2.磁盘容量

        一个磁盘上可以记录的最大位数称为它的最大容量,或简称容量。磁盘容量是由以下技术因素决定:

        ① 记录密度(recording density)(位/英寸):磁道一英寸的段中可以放入的位数。

        ② 磁道密度(track density)(位/英寸):从盘片中心出发半径上一英寸的段内可以有的磁道数。

        ③ 面密度(areal density)(位/平方英寸):记录密度与磁道密度的乘积。 

        最初的磁盘,在面密度很低的时代下设计的,将每个磁道分为数目相同的扇区扇区的数目是由最靠内的磁道能记录的扇区数决定的。为了保持每个磁道有固定的扇区数,越往外的磁道扇区隔得越开。 不过,随着面密度的提高,扇区之间的间隙(没有存储数据位)变得不可接受地大,因此,现代大容量磁盘使用一种多区记录的技术,柱面的集合被分割成不相交的子集合,称为记录区。每个区包含一组连续的柱面。一区中的每个柱面中的每条磁道都有相同数量的扇区,这个扇区数量是由该区最里面的磁道所能包含的扇区数决定的。

f7dae6de0eb74da08cddbcf5c4497246.png 3.磁盘操作

        磁盘用读/写头(read/write head)来读写存储在磁性表面的位,而读写头连接到一个传动臂一段,如图6-10a所示。通过沿着半径轴前后移动这个传动臂驱动器可以将读/写头定位在盘面上的任何磁道上。这样的机械运动称为寻道。一旦读/写头定位到了期望的磁道上,那么当磁道上的每个位通过它的下面时,读/写头可以感知到这个位的值(读该位),也可以修改这个位的值(写该位)。有多个盘片的磁盘针对每个盘面都有一个独立的读/写头,如图6-10b。读/写头垂直排列,一致行动。在任何时刻,所有的读/写头都位于同一个柱面上0bced67cf20e498da4f48d4295c37ccd.png

         在传动臂末端的读/写头在磁盘表面高度大约 0.1 微米处的一层薄薄的气垫上飞翔,速度大约为80km/h。在这样小的间隙里,盘面上一粒细小的灰尘都像一块巨石。如果读/写头碰到了这样的一块巨石,读/写头会停下来,撞到盘面——所谓的读/写头冲撞,为此,磁盘总是密封包装的。

        磁盘以扇区大小的块来读写数据。对扇区的访问时间有三个主要部分:寻道时间,旋转时间和传送时间

        ① 寻道时间:为了读取某个扇区的内容 ,传动臂首先将读/写头定位到包含目标扇区的磁道上移动传动臂所需的时间称为寻道时间。寻道时间Tseek依赖于读/写头以前的位置传动臂在盘面上移动的速度。现代驱动器中平均寻道时间Tavgseek是通过对几千次对随机扇区的寻道求平均值来测量的,通常为 3~9 ms。一次寻道的最大时间 Tmaxseek 可以高达 20ms

        ② 旋转时间:一旦读/写头定位到了期望的磁道,驱动器等待目标扇区的第一个位旋转到读/写头下。这个步骤的性能依赖于当读/写头到达目标扇区时盘面的位置以及磁盘的旋转速度。在最坏的情况下,读/写头刚刚错过了目标扇区,必须等待磁盘转一整圈。因此,最大旋转延迟(以秒为单位)是db22d60b3a8a42bfa0818e30adb68cba.png

         ③ 传送时间当目标扇区的第一个位位于读/写头下,驱动器就可以开始读或者写扇区的内容了。一个扇区的传送时间依赖于旋转速度每条磁道的扇区数目。因此,可以粗略估计一个扇区以秒为单位的平均传送时间如下3dff8db188474e7f8efc65326b03fc5c.png

说明:

        ①访问一个磁盘扇区中512个字节的时间主要是寻道时间旋转延迟,访问扇区中的第一个字节用了很长时间,但访问剩下的字节几乎不用时间。

        ② 因为寻道时间和旋转延迟大致相等,所以寻道时间乘2是估计磁盘访问时间的简单合理方法

        ③ 对存储在 SRAM 中的一个 64位的访问时间大约是 4ns,对 DRAM 的访问时间是60ns,因此,从内存中读一个 512 个字节扇区大小的块的时间对SRAM 大约是256ns,对 DRAM是 4000ns。磁盘访问时间,大约10ms,是SRAM 的大约40000倍,是DRAM的2500倍。

        4. 逻辑磁盘块

        一个 B 个扇区大小的逻辑块的序列,编号为 0,1....,B-1。磁盘封装中有一个小的硬件/固件设备,称为磁盘控制器维护着逻辑块号和实际(物理)磁盘扇区之间的映射关系。 

        当操作系统想要执行一个 I/O 操作时,例如读一个磁盘扇区的数据到主存,操作系统会发送一个命令到磁盘控制器,让它读某个逻辑块号控制器上的固件执行一个快速表查找,将一个逻辑块号翻译成一个(盘面,磁道,扇区)的三元组,这个三元组唯一地标识了对应的物理扇区。控制器上的硬件会解释这个三元组,将 读/写头移动到适当的柱面,等待扇区移动到读/写头下,将读/写头感知到的位放到控制器上的一个小缓冲区然后复制到主存中

        5.连接 I/O 设备 

        例如图形卡,监视器,鼠标,键盘和 磁盘这样的输入/输出(I/O)设备。都是通过 I/O 总线,例如 Intel 的外围设备互连总线连接到 CPU 和 主存的。系统总线和内存总线是与CPU 相关的,与它们不同,诸如 PCI 这样的 I/O 总线设计成与底层 CPU 无关。例如,PC 和 Mac 都可以使用 PCI 总线。图 6-11 展示了一个典型的 I/O 总线结构,它连接了 CPU,主存和I/O设备

        虽然 I/O 总线比系统总线和内存总线慢但是可以容纳种类繁多的第三方 I/O设备,在图6-11中,有三种不同类型的设备连接到总线

        ① 通用串行总线(USB)控制器是一个连接到 USB 总线的设备的中转机构,USB 总线是一个广泛使用的标准,连接各种外围I/O设备,包括键盘,鼠标,调制解调器,数码相机,游戏操纵杆,打印机,外部磁盘驱动器和固态硬盘。

        ② 图形卡(或适配器)包含硬件软件逻辑,它们负责代表CPU在显示器上画像素

        ③ 主机总线适配器将一个或多个磁盘连接到 I/O 总线,使用的是一个特别的主机总线接口定义的通信协议。两个最常用的这样的磁盘接口是 SCSI 和 SATA。 SCSI 磁盘比 SATA 驱动器更快但是也更贵,SCSI 主机总线适配器(SCSI 控制器)可以支持多个磁盘驱动器,与 SATA 适配器不同,它只能支持一个驱动器

0e8cf9a6b3f84bf7bf0f1f5c5e1e84ba.png

         其他的设备,例如网络适配器,可以通过将适配器插入到主板上空的扩展槽中,从而连接到 I/O 总线 ,这些插槽提供了到总线的直接电路连接。

        6. 访问磁盘

        详细描述 I/O 设备是如何工作以及如何对它们进行编程超出了讨论的范围,但可以给出一个概要描述,例如图6-12 总结了当 CPU 从磁盘读取数据时发生的步骤

        CPU 使用一种称为 内存映射I/O 的技术来向 I/O 设备发射命令(6-12a)。在使用内存映射I/O的系统中,地址空间中有一块地址是为与I/O设备通信保留的。这样的地址称为一个I/O端口。当一个设备连接到总线时,它与一个或多个端口相关联(或被映射到一个或多个端口)。

c1b6789230bd43ea89fc31c486a5e417.png

         假设磁盘控制器映射到端口 0xa0,随后,CPU 可能通过执行三个对地址 0xa0 的存储指令,发起磁盘读:第一条指令是发送一个命令字,告诉磁盘发起一个读,同时还发送了其他参数,例如当读完成时,是否中断 CPU。第二条指令指明应该读的逻辑块号。第三条指令指明存储磁盘扇区内容的主存地址

        当 CPU 发出了请求之后,在磁盘执行读的时候,它通常会做些其他的工作。回想一下,一个 1GHZ 的处理器时钟周期为 1ns,在用来读磁盘的 16ms 时间里,它潜在地可能执行 1600万条指令。 在传输进行时,只是简单地等待,什么都不做,是一种极大的浪费。

        在磁盘控制器收到来自 CPU 的读命令后,它将逻辑块号翻译成一个扇区地址读该扇区的内容,然后将这些内容直接传送到主存,不需要CPU的干涉(6-12b)。 设备可以自己执行读或者写总线事务而不需要 CPU 干涉的过程,称为直接内存访问这种数据传送称为 DMA 传递。

        在 DMA 传送完成,磁盘扇区的内容被安全的存储在主存以后,磁盘控制器通过给 CPU 发送一个中断信号来通知 CPU(6-12c),基本思想是中断会发信号到CPU芯片的一个外部引脚上。这回导致 CPU暂停当前正在做的工作,跳转到一个操作系统例程。这个程序会记录下 I/O 已经完成,然后将控制返回到 CPU 被中断的地方。 

6.1.3 固态硬盘

        固态硬盘(SSD)是一种基于闪存的存储技术,在某些情况下是传统旋转磁盘的极有吸引力的替代产品。图6-13 展示了其基本思想,SSD封装插到 I/O 总线上标准硬盘插槽(通常是USB或SATA)中, 行为和其他硬盘一样,处理来自CPU的读写逻辑磁盘块的请求一个 SSD 封装由一个或多个闪存芯片和闪存翻译层组成闪存芯片替代传统旋转磁盘中的机械驱动器,而闪存翻译层是一个硬件/固件设备,扮演与磁盘控制器相当的角色,将对逻辑块的请求翻译成对底层物理设备的访问4cab33c77c9345e5aba702ad75612f14.png

         图 6-14 展示了典型 SSD 的性能特性。注意,读 SSD 比写要块。随机读和写的性能差别是由底层闪存基本属性决定的。如图6-13,一个闪存由B个块的序列组成,每个块由P页组成。通常,页的大小是 512 字节~4KB块是由 32~128页组成的块的大小为16KB~512KB数据是以页为单位读写的只有在一页所属的块整个被擦除后,才能写这一页(通常指该块中的所有位都被设置为1)。不过,一旦一个块被擦除了,块中每一页可以不需要再进行擦除就写一次。大约进行100000次重复写之后,块就会磨损坏。一旦块被磨损坏了,就不能使用了。

e20f46388ea947ed8eab1424397caeb8.png         随机写很慢,①擦除块需要较长的时间,1ms级的,比访问页所需时间要高一个数量级。其次,如果写操作试图修改一个包含已经有数据(不是全为1)的页,那么这个块中所有带有数据的页都必须被复制到一个新(擦除过的)块然后才能进行对页P的写

        比起旋转磁盘,SSD有很多优点。 由半导体存储器构成,没有移动的部件,因而随机访问时间比旋转磁盘要快,能耗更低,同时也更结实。不过有缺点,反复写之后,闪存块会磨损,SSD也容易磨损。闪存翻译层中的平均磨损逻辑试图将擦除平均分布在所有的块上来最大化每个块的寿命。实际上,平均磨损逻辑处理得非常好,要很多年SSD才会磨损坏。

6.1.4 存储技术趋势

        存储技术的讨论中,几个重要的思想:

        ① 不同的存储技术有不同的价格和性能折中。SRAM比DRAM快一点,而 DRAM 比磁盘要快很多。另一方面,快速存储总是比慢速存储要贵的。SRAM每字节的造价比DRAM高, DRAM的造价又比磁盘高的多。SSD 位于 DRAM 和 旋转磁盘之间。

        ② 不同存储技术的价格和性能属性以截然不同的速率变化着。

75ff27658d5643dcacddc4d27397db01.png

        ③ DRAM 和磁盘的性能滞后于 CPU 的性能。 有效周期时间——定义为一个单独的CPU(处理器)的周期时间除以它的处理器核数

4770f009c303432b8f1f0576f539b79e.png

         注意,虽然 SRAM 的性能滞后于 CPU 的性能,但还是在保持增长。不过,DRAM 和 磁盘性能与CPU性能之间的差距实际上是在加大的。直到 2003 年左右多核处理器的出现,这个性能差距都是延迟的函数DRAM 和 磁盘的访问时间比单个处理器的周期时间提高得更慢。 不过,随着多核的出现,这个性能越来越成为了吞吐量的函数,多个处理器核并发地向 DRAM 和磁盘发请求。

        下图6-16 清楚地表明了各种趋势,以半对数为比例,画出了图6-15中的访问时间和周期时间

ea4e1473900b48968faf1efa2fa42c92.png

6.2 局部性

        一个编写良好的计算机程序常常具有良好的局部性。就是,它们倾向于引用邻近于 其他最近引用过的数据项 的数据项,或者最近引用过的数据项本身。 这种倾向性,被称为 局部性原理,是一个持久的概念,对硬件和软件系统的设计和性能都有极大的影响。

        局部性通常有两种不同的形式:时间局部性和空间局部性。在一个具有良好时间局部性的程序中,被引用过一次的内存位置很可能在不远的将来再被多次引用。 在一个具有良好空间局部性的程序中,如果一个内存位置被引用了一次,那么程序很可能在不远的将来引用附近的一个内存位置

        理解为:有良好局部性的程序比局部性差的程序运行得更快。 现代计算机系统的各个层次,从硬件到操作系统,再到应用程序,它们的设计都利用了局部性。

        在硬件层,局部性原理允许计算机设计者通过引入称为 高速缓存存储器 的小而快速的存储器来保存最近被引用的指令和数据项,从而提高对主存的访问速度。

        在操作系统级,局部性原理允许系统使用主存作为虚拟地址空间最近被引用块的高速缓存。类似的,操作系统用主存来缓存磁盘文件系统中最近被使用的磁盘块。

6.2.1 对程序数据引用的局部性

        考虑图 6-17a 中的简单函数,它对一个向量的元素求和。这个例子中,变量 sum 在每次循环迭代中被引用一次,因此,对于 sum 来说,有好的时间局部性。 另一方面,因为 sum 是标量,没有空间局部性56156c8d150a4768888822f182cfa51b.png

        在 6-17b 中看到,向量 v 的元素是被顺序读取的,一个接一个,按照它们存储在内存中的顺序,因此对于变量v,函数有很好的空间局部性,但是时间局部性很差,因为每个向量元素只被访问一次。因为对于循环体中的每个变量,这个函数要么有好的空间局部性,要么有好的时间局部性,所以我们可以断定 sumvec 函数有良好的局部性。

        像 sumvec 这样顺序访问一个向量每个元素的函数,具有步长为 1 的引用模式(相对于元素的大小)。有时称步长为 1 的引用模式为 顺序引用模式。一个连续向量中,每隔 k 个元素进行访问,就称为 步长为 k 的引用模式。步长为 1 的引用模式是程序中空间局部性常见和重要的来源。一般而言,随着步长的增加,空间局部性下降

        对于引用多维数组的程序而言,步长也是一个重要的问题。 例如考虑 6-18a 中的函数 sumarrayrows,它对一个二维数组的元素求和。 双重嵌套循环按照 行优先顺序读数组的元素,也就是,内层循环读第一行的元素,然后读第二行,以此类推。函数 sumarraryrows 具有良好的空间局部性,因为它按照数组被存储的行优先顺序来访问这个数组,其结果是得到一个很好的步长为 1 的引用模式,具有良好的空间局部性。

457f55fac638493ea3c28754a2d7f161.png         一些看上去很小的对程序的改动能够对它的局部性有很大的影响。例如,图6-19a 中的函数 sumarraycols 计算的结果和图 6-18a 中函数 sumarraryrows 的一样。唯一的区别是我们交换了 i 和 j 的循环。这样交换循环的影响:空间局部性很差,因为它按照列顺序来扫描数组,而不是行顺序。 因为 C 数组在内存中是按照行顺序来存放的,结果就得到步长为 N 的引用模式,如图6-19b

d37324bfb9724d81bf8d05b6c6735c69.png 6.2.2 取指令的局部性

        程序指令是存放在内存中的,CPU 必须取出(读出)这些指令,所以也能够评价一个程序关于取指令的局部性。例如,for 循环体里的指令是按照连续的内存顺序执行的,因此循环有良好的空间局部性,因为循环体会被执行多次,所以它也有很好的时间局部性。

        代码区别于程序数据的一个重要属性是在运行时它是不能被修改的。当程序正在执行时,CPU只从内存读出它的指令。CPU 很少会重写和修改这些指令的。

6.2.3 局部性小结

        ① 重复引用相同变量的程序有良好的时间局部性

        ② 对于具有步长为 k 的引用模式的程序,步长越小,空间局部性越好。具有步长为 l 的引用模式的程序有很好的空间局部性。在内存中以大步长跳来跳去的程序空间局部性很差。

        ③ 对于取指令来说,循环有好的时间和空间局部性。循环体越小,循环迭代次数越多,局部性越好。 

6.3 存储器层次结构

        存储技术:不同存储技术的访问时间差异很大。速度较快的技术每字节的成本要比速度较慢的技术高,而且容量较小。CPU 和主存之间的速度差距在增大。

        计算机软件:一个编写良好的程序倾向于展示出良好的局部性。

         硬件和软件的这些基本属性互相补充得很完美。这种相互补充的性质想到一种组织存储器系统的方法,称为 存储器层次结构,所有的现代计算机系统中都使用了这种方法。图 6-21 展示了一个典型的存储器层次结构。一般而言,从高层往底层走,存储设备变得更慢,便宜和大。最高层(L0),是少量快速的CPU寄存器,CPU可以在一个时钟周期内访问它们。接下来是一个或多个小型到中型的基于SRAM 的高速缓存存储器,可以在几个 CPU时钟周期内访问他们。然后是一个大的基于 DRAM 的主存,可以在几十到几百个时钟周期内访问它们。接下来是慢速但是容量很大的本地磁盘。最后,有些系统甚至包括了一层附加的远程服务器上的磁盘,要通过网络来访问。

57b149e7e519467eb1277100d487e34e.png

6.3.1 存储器层次结构中的缓存

        高速缓存(cache)是一个小而快速的存储设备,它作为存储在更大,也更慢的设备中的数据对象的缓冲区域。使用高速缓存的过程称为缓存。

        存储器层次结构的中心思想,对于每个 k,位于 k 层的更快更小的存储设备作为位于 k+1 层的更大更慢的存储设备的缓存。 换句话说,层次结构的每一层都缓存来自较低一层的数据对象。例如,本地磁盘作为通过网络从远程磁盘取出的文件的缓存,主存作为本地磁盘上数据的缓存,以此类推,最小的缓存——CPU寄存器组。

        图 6-22 展示了存储器层次结构中缓存的一般性概念。第 k+1 层的存储器被划分成连续的数据对象组块,称为块。每个块都有唯一的地址和名字,使之区别于其他的块。块是可以固定大小的,也可以是可变大小的。例如,图6-22中第 k+1 层存储器被划分成 16 个大小固定的块,编号为0~15

         类似的,第 k 层的存储器被划分成较少的块的集合,每个块的大小与 k+1 层的块的大小一样。在任何时刻,第 k 层的缓存包含第 k+1 层块的一个子集的副本13720a4dbdb445609a83cbe1f282bcd2.png

        数据总是以块大小为传送单元在第 k 层和第 k+1 层之间来回复制的。虽然在层次结构中任何一对相邻的层次之间块大小是固定的,但是其他的层次对之间可以有不同固定块大小。例如在图6-21中,L1和L0 之间传送通常使用的是 1 个字大小的块L2 和 L1 之间(以及 L3 和 L2之间,L4 和 L3 之间)的传送通常使用的是几十个字节的块。而 L5 和 L4 之间传送用的是大小为几百或几千字节的块。 一般而言,层次结构中较低层(离CPU较远)的设备访问时间较长,为了补偿这些较长的访问时间,倾向于用较大的块。

        1. 缓存命中

        当程序需要第 k+1 层的某个数据对象d时,它首先在当前存储在第 k 层的一个块中查找d。如果 d 刚好缓存在第 k 层中,那么就是所说的缓存命中。该程序直接从第 k 层读取 d,根据存储器层次结构的性质,这要比从第 k+1 层读取 d 更快。例如,有一个良好时间局部性的程序可以从块14中读出一个数据对象,得到一个对第 k 层的缓存命中。        

        2. 缓存不命中

        另一方面,如果第 k 层中没有缓存数据对象 d,那么就是所说的缓存不命中。当发生缓存不命中时,第 k 层的缓存从第 k+1 层缓存中取出包含 d 的那个块,如果第 k 层的缓存已经满了,可能会覆盖现存的一个块。

        覆盖一个现存的块的过程称为替换驱逐这个块。被驱逐的块有时也称为牺牲块。决定该替换的哪个块是由缓存的替换策略来控制的。例如,一个具有随机替换策略的缓存会随机选择一个牺牲块。一个具有最近最少被使用(LRU)替换策略的缓存会选择那个最后被访问的时间距现在最远的那个块。 

        3. 缓存不命中的种类

        区分不同种类的缓存不命中有时候是很有帮助的。如果第 k 层的缓存是空的,那么对任何数据对象的访问都会不命中。一个空的缓存有时被称为冷缓存,此类命中称为① 强制性不命中 冷不命中冷不命中不会在反复访问存储器使得缓存暖身之后的稳定状态中出现

        只要发生了不命中,第 k 层的缓存就必须执行某个放置策略,确定把它从第 k+1 层中取出的块放在哪里。最灵活的替换策略是允许来自第 k+1 层的任何块放在第 k 层的任何块中。对于存储器层次结构中高层的缓存(靠近CPU),它们是用硬件来实现的,而且速度最优,这个实现起来通常非常昂贵,因为随机地放置块,定位起代价很高。

         因此,硬件缓存通常使用的是更严格的放置策略,这个策略将第 k+1 层的某个块限制放置在第 k 层块的一个小的子集中。例如,图6-22中,可以确定第 k+1 层的块 i 必须放置在第 k 层的块(i mod 4)中。例如第 k+1 层的块0 4 6 12 会映射到第 k 层的块0;块 1 5 9 13 会映射到块 1.图 6-22 中实例缓存就是这个策略。

        这种限制性的放置策略会引起一种不命中,称为②冲突不命中,在这种情况中,缓存足够大,能够保存被引用的数据对象,但是因为这些对象会映射到同一个缓存块,缓存会一直不命中。例如6-22中,如果程序请求块 0,然后块8,然后块0,以此类推,在第 k 层的缓存中,对这两个块的每次引用都不会命中,即使这个缓存总共可以容纳 4 个块。

        程序通常是按照一系列阶段(如循环)来运行的,每个阶段访问缓存块的某个相对稳定不变的集合。 例如,一个嵌套的循环可能会反复地访问同一个数组的元素。这个块的集合称为这个阶段的工作集。当工作集的大小超过缓存的大小时,缓存会经历③容量不命中。就是缓存太小了,不能处理这个工作集。

        4.缓存管理

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

         例如,编译器管理寄存器文件,缓存层次结构的最高层。它决定当发生不命中时何时发射加载,以及确定哪个寄存器来存放数据。L1 L2 L3 层的缓存完全是由内置在缓存中的硬件逻辑来管理的。在一个由虚拟内存的系统中,DRAM 主存作为存储在磁盘上的数据块的缓存,是由操作系统软件和 CPU 上的地址翻译硬件共同管理的。对于一个具有像 AFS 这样的分布式文件系统的机器来说,本地磁盘作为缓存,它是由运行在本地机器上的 AFS 客户端进程管理的,在大多数时候,缓存都是自动运行的,不需要程序采取特殊或显示的行动。

6.3.2 存储器层次结构概念小结

        基于缓存的存储器层次结构行之有效,是因为较慢的存储设备比较快的存储设备更便宜,还因为程序倾向于展示局部性。

        利用时间局部性:同一数据对象可能会被多次使用。一旦一个数据对象在第一次不命中时被复制到缓存中,就会期望后面对该目标有一系列的访问命中。因为缓存比低一层的存储设备更快,对后面命中的服务会比最开始的不命中快很多。

        利用空间局部性:块通常包含多个数据对象。由于空间局部性,会期望后面对该块中其他对象的访问能够补偿不命中后复制该块的花费。

现代系统中到处都使用了缓存。如图6-23中,CPU芯片,操作系统,分布式文件系统和万维网都是用了缓存。各种各样硬件和软件的组合构成和管理着缓存。1de208c4c46643058b6db1c94d6e09bb.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值