csapp第六章 存储器层次结构

在简单模型中,存储器系统是一个线性的字节数组,而cpu能够在一个常数时间内访问每个存储器位置。

实际上,存储器系统是一个具有不同容量、成本和访问时间的存储设备的层次结构。

存储器层次结构是可行的。整体效果是一个大的存储器池,其成本与层次结构底层最便宜的存储设备相当,但是却以接近于层次结构顶部存储设备的高速率向程序提供数据。

计算机系统中一个基本而持久的思想:如果你理解了系统是如何将数据在存储器层次结构中上下移动的,那么你就可以编写你的应用程序,使得它们的数据项存储在层次结构较高的地方,在那里cpu能更快的访问它们。

这个思想围绕着计算机程序的一个称为局部性的基本属性。

在本章中,我们会看看基本的存储技术,并描述它们是如何被组织成层次结构的。

6.1 存储技术

随机访问存储器分为两类:静态,动态。SRAM比DRAM更快,更贵。SRAM作为高速缓存存储器。DRAM作为主存。

SRAM将每个位存储在一个双稳态存储单元里。只要有电,它就保持他的值。

DRAM将每个位存储为对一个电容的充电。DRAM单元在10-100ms内失去电荷,所以需要刷新或者其他的方法保证数据正确性。

DRAM表示一般写成N*W,w是一个单元的位数,N是单元数。本身称这个单元是超单元。然后N又表示为r*c,这样的表示是寻址的时候地址引脚不会太多,比如N=16,就要4个引脚。4*4的话,4需要两个引脚。但是这种二维阵列组织有个缺点:两步发送地址,增加了访问时间。

DRAM的增强型有:FPM DRAM,EDO DRAM,SDRAM,DDR SDRAM(DDR,DDR2,DDR3),Random DRAM,VRAM。

PC使用的DRAM历史:95之前FPM,96-99EDO,-02SDRAM和DDR,-10DDR3。

非易失性存储器,SRAM和DRAM都是易失的。

ROM称为只读存储器是历史原因,很多ROM都是可写的。ROM的分类是以它们能够被重编程(写)的次数和对他们进行重编程的机制来划分的。

ROM包括:PROM,EPROM,EEPROM,闪存(基于EEPROM)。

存储在ROM设备中的程序通常称为固件。

总线事物:读事物——从主存传送数据到cpu,写事物——从cpu传送数据到内存。

磁盘是广为应用的保存大量数据的存储设备:盘片,表面,主轴,RPM,磁道,扇区,柱面。

对于SRAM和DRAM,KMGT通常是1024为基,但对于磁盘,KMGT以1000为基。

像图形卡,监视器,鼠标,键盘和磁盘这样的I/O设备,都是通过I/O总线(PCI)连接到cpu和主存的。

系统总线和存储器总线是与cpu总线相关的,但pci这样的总线和底层cpu无关。

I/O总线总是比系统总线和存储器总线慢,但是它可以容纳种类繁多的第三方I/O设备。主机总线适配器将一个或多个磁盘连接到I/O总线,最常用的是SCSI和SATA,前者更贵,更快。

cpu使用一种称为存储器映射I/O的技术,在使用该技术的系统中,地址空间中有一块地址是为与I/O设备通信保留的。每个这样的地址称为一个I/O端口。当一个设备连接到总线上时,它与一个或多个端口相联系。

cpu从磁盘读数据时发生的步骤:cpu通过将命令、逻辑块号和目的存储器地址写到与磁盘相关联的存储器映射地址,发起一个磁盘读;磁盘控制器读扇区,并执行到主存的DMA传送;DMA传送完成时,磁盘控制器用中断的方式通知CPU。

现代磁盘将他们的构造呈现为一个简单的视图,一个B个扇区大小的逻辑块序列。磁盘控制器维护着逻辑块号和实际(物理)磁盘扇区之间的映射关系。这里看到,逻辑块对应扇区。

SSD包,由一个或多个闪存芯片和闪存翻译层组成。

存储器和磁盘技术的一个基本事实:增加密度比降低访问时间更容易。

DRAM和磁盘的性能滞后于cpu的性能。现代计算机频繁的使用基于SRAM的高速缓存,试图弥补处理器-存储器之间的差距。这种方法可行是因为应用程序的局部性。

6.2 局部性

一个编写良好的计算机程序尝尝具有良好的局部性。也就是说,他们倾向于引用临近于其他最近引用过的数据项的数据项,或者最近引用过的数据项本身。

这种倾向性,被称为局部性原理,是一个持久的概念,对硬件和软件系统的设计和性能都有着极大的影响。

局部性通常有两种不同的形式:时间局部性和空间局部性。

两者的区别在于时间对的是一个存储器位置,空间对的是附近的存储器位置。

被引用过一次的存储器位置很可能在不远的将来再被多次引用——时间。一个存储器位置被引用了一次,那么程序很可能在不远的将来引用附近的一个存储器位置——空间。

对于空间局部性,步长为1的引用模式称为顺序引用模式,这种模式具有最好的空间局部性,如数组,一个一个的顺序访问具有最好的空间局部性。

多维数组,按照行优先顺序,具有最好的空间局部性。

量化评价一个程序中局部性的简单原则:

  • 重复引用同一个变量的程序有良好的时间局部性。
  • 对于具有步长为k的引用模式的程序,步长越小,空间局部性越好。具有步长为1的引用模式的程序有很好的空间局部性。
  • 对于取指令来说,循环有好的时间和空间局部性。循环体越小,循环迭代次数越多,局部性越好。

6.3 存储器层次结构

存储器层次结构是组织存储器系统的方法,人想的,现在所有的计算机系统都使用了这种方法。

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

存储器层次结构的中心思想是:对于每个k,位于k层的更快更小的存储设备作为位于k+1层的更大更慢的存储设备的缓存。

也就是说层次结构的每一层都缓存来自较低一层的数据对象。

这里必须强调一下,这也就是说数据时不可以越级的吗?

数据总是以块大小为传送单元在第k层和第k+1层之间来回拷贝的。例子:L1和L0的传送是1个字的块,L2和L1之间是8-16个字的块。

一些概念:缓存命中,缓存不命中,牺牲块,替换策略,冷缓存,强制性不命中,冷不命中,放置策略,冲突不命中,容量不命中。

  • 编译器管理寄存器文件,缓存层次结构的最高层。
  • L1,L2和L3的缓存完全是由内置在缓存中的硬件逻辑来管理的。
  • DRAM主存作为存储在磁盘上的数据块得缓存,是由操作系统和cpu上的地址翻译硬件共同管理的。
  • AFS这样的分布式文件系统,本地磁盘作为缓存,它是由运行在本地机器上的AFS客户端进程管理的。

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

6.4 高速缓存存储器

早期计算机系统的存储器层次结构只有三层:cpu寄存器,DRAM主存,磁盘。随着cpu和主存之间差距的逐渐增加,系统设计者被迫加入了SRAM高速缓存存储器,称为L1/L2/L3高速缓存。

L1通常需要2-4个时钟周期,L2通常需要10个时钟周期,L3通常需要30-40个时钟周期。

高速缓存存储器结构的一些细节:直接映射高速缓存,组相联高速缓存,全相联高速缓存。

高速缓存参数的性能影响:不命中率,命中率,命中时间,不命中处罚。

(这一节,了解一些硬件知识,结构的细节不管了)

6.5 编写高速缓存友好的代码

局部性比较好的程序更容易有较低的不命中率,而不命中率较低的程序往往比不命中率较高的程序运行的更快。

下面就是我们用来确保代码高速缓存友好的基本方法:

让最常见的情况运行得快。程序通常把大部分时间都花在少量的核心函数上,而这些函数通常把大部分时间都花在了少量循环上。

每个循环内部缓存不命中数量最小。(对局部变量的反复引用是好的,步长为1的引用模式是好的)

6.6 综合:高速缓存对程序性能的影响

存储器系统的性能不是一个数字就能描述的,相反,它是一座时间和空间局部性的山,这座山的上升高度差别可以超过一个数量级。明智的程序员会试图构造他们的程序,使得程序运行在山峰而不是低谷。

还是这几项,推荐的技术:

  • 将你的注意力集中在内循环上,大部分计算和存储器访问都发生在这里。
  • 通过按照数据对象存储在存储器中的顺序、以步长为1的来读数据,从而使得你程序中的空间局部性最大。
  • 一旦从存储器中读入了一个数据对象,就尽可能多的使用它,从而使得程序中的时间局部性最大。

6.7 小结

(over)

posted @ 2012-05-03 09:52  ray hill  阅读(464)  评论(0编辑  收藏  举报