展示计算机存储器展示的类型、技术、组成、性能和成本等方面。
4.1 计算机存储系统概述
4.1.1 存储系统的特性
根据存储系统关键特性对其进行分类:
1.位置:内部和外部;
2.传输单位:字和块;
3.访问方式:顺序、直接、随机和相联;
4.性能:访问时间、周期时间和传输速率;
内部存储器的三个相关概念:
1.传输单位:对内部存储器而言,传输单位等于进出存储器模块的电线条数,对于外部存储器来说,数据通常比一个字大得多的单位来传输,它们被称为块;
2.字:存储器组织的"天然"单位;
3.可寻址单元:地址位数A与可寻址单元N之间的关系是2^A=N;
存储器之间的另一个区别是访问数据单元的方式:
1.顺序访问:使用了共享读写机制,必须从当前位置移动到目标位置,经过并不访问的每个中间记录。因此,对于任意记录的访问时间是高度变化的。磁带属于此类;
2.直接访问:访问是通过直接访问一般邻近区域以及顺序搜索/计数或等待达到最终位置来完成。磁盘属于此类;
3.随机访问:对给定位置的访问时间是恒定 ,与之前的访问顺序无关。可以随机的选择任何位置并直接寻址和访问,主存和某些高速缓存系统就是随机访问;
4.相联:这是随机访问类型的存储器,允许用户对指定匹配的字所需位置进行比较。对一个字的检索是基于其部分内容,而不是其地址。
从用户角度来说,存储器最显著两个特性是容量和性能;
1.访问时间(延迟):对随机访问存储器而言,访问时间是执行读或写操作所消耗的时间,即从地址呈现给存储器到数据已经存储或可供使用的时间间隔。对于非随机访问而言,访问时间是将读写机制定位到所需位置的时间。
2.存储周期时间:该概念主要用于随机访问存储器,它包含了访问时间和第二次访问开始前所需的所有额外时间。注意,存储器周期时间与系统总线有关,与处理器无关。
3.传输速率:数据传输到存储器单元或从存储器单元传输出去的速率;
对于随机访问存储器来说,组织是关键的设计问题。组织是指组成字的位的物理排列。
4.1.2 存储器层次结构
计算机存储的设计限制可以归结为三个问题:多大?多快?多贵?
存储器的三个关键特性之间存在权衡:容量、访问时间和成本。关系如下:
1.访问时间越快,每位成本越高;
2.容量越大,每位成本越低;
3.容量越大,访问时间越长;
设计人员希望使用大容量存储器,不仅因为需要容量,还因为每位成本较低。但是,为了性能需求,设计人员又需要使用昂贵的、容量相对较小的、访问时间较短的存储器。
这个困境的出路在于不要依赖单一的存储器组件或技术,而是利用存储器层次结构。这种组织结构成功的关键在于降低访问频率。当沿着存储器金字塔结构向下走时,会发生下列情况:
A.降低每位成本;
B.增加容量;
C.增加访问时间;
D.降低处理器访问该存储器的频率;
使用2级存储器来减少平均访问时间是可行的,但是必须a到d条件适用才行。通过采用各种技术,存在满足条件a和c的存储系统,条件d一般也有效。
条件d有效的基础是访问局部性的原理。在一个程序执行期间,不论是指令还是数据,处理器对内存的访问往往比较集中。程序通常包含许多迭代循环和子例程。一旦进入循环或子例程,就会重复引用一小部分指令。同样,对表格或数组的操作涉及访问数据子集。
高速缓存通常对程序员是不可见的,它是一种执行主存与寄存器之间数据移动的设备。
4.2 高速缓存存储器原理
设计高速缓存是为了把昂贵高速存储器的访问时间与便宜低速存储器的大容量结合起来。
由于访问的局部性现象,当一个数据块为了满足一次内存引用而被获取高速缓存时,很有可能将来也会对同一内存位置或该数据块中其他字的引用。
为了映射,把内存看作有许多固定长度的块构成,每个块包含k个字。主存有m=2^n/k个块。高速缓存由m个块构成,每个块称为一个行。每行包括k个字,以及一个由若干位组成的标签。
若块数大于行数,每个行都不会唯一且永久的专用于一个特定的块。因此,每个行都有一个标签来指明当前存放的那个特定块。
若处理器要访问的字已经在高速缓存中,它就被传送到处理器。否则,包含这个字的主存块就会被加载到高速缓存,这个字然后被传送到处理器。
在当代高速缓存的典型结构中,高速缓存通过数据线、控制线和地址线与处理器相连。数据线和地址线还连接数据和地址缓冲区,这些缓冲区又连接到通往主存的系统总线。当发生高速缓存命中时,数据和地址缓冲区被禁用,通信只在处理器和高速缓存之间进行,无需系统总线。当发生高速缓存缺失时,所需地址被加载到系统总线,数据通过数据缓冲区返回给高速缓存和处理器。
4.3 高速缓存设计要素
如果对应用程序软件进行调整以利用高速缓存,那么高速缓存层次结构可以用于提高性能。
高速缓存地址 | 写策略 | 替换算法 |
逻辑地址 | 写直达 | 最近最少使用 |
物理地址 | 写回 | 先进先出 |
高速缓存大小 | 行大小 | 最少使用 |
映射函数 | 高速缓存数量 | 随机 |
直接 | 一层或两层 | |
全相联 | 混合或分离 | |
组相联 |
4.3.1 高速缓存地址
从本质上来看,虚拟内存是一种允许程序从逻辑角度来寻找存储器的工具,它不从物理上考虑主存的可用容量。读写主存时,存储器管理单元mmu硬件把每个虚拟地址转换为主存中的物理地址。
使用虚拟地址时,选择把高速缓存放在处理器与mmu之间,或是mmu与主存之间。前者为逻辑高速缓存,后者为物理高速缓存。逻辑高速缓存用虚拟地址保存数据,处理器直接访问高速缓存,不用经过mmu。物理高速缓存用主存物理地址保存数据。
逻辑高速缓存的一个明显优势是访问它的速度快于访问物理高速缓存,因为它可以在mmu执行地址转换之前进行响应。缺点在于,大多数虚拟内存系统为每个应用程序提供相同的虚拟内存地址空间。因此同一个虚拟地址在两个完全不同的应用程序中会指向两个不同的物理地址。所以,每个应用程序上下文交换时必须完全刷新高速缓存存储器,或是每个高速缓存行增加额外的位来指明地址指向的虚拟地址空间。
4.3.2 高速缓存大小
我们即希望高速缓存足够小,以便其总体平均每位成本接近单独的主存,又希望它足够大,以便其整体的平均访问时间接近于单独的高速缓存。最小化高速缓存大小还有其他几个动机。高速缓存越大,用于寻址该缓存的门电路就越多,速度就慢下来了。
4.3.3. 映射函数
由于高速缓存行比主存块较少,需要用算法把主存块映射到高速缓存行。此外,还需要有某种方式来确定一个主存块当前要占用那个高速缓存行。映射函数的选择决定了高速缓存的组织方式,使用的技术有直接映射、全相联映射和组相联映射。
1.直接映射:把每个主存块映射到唯一可能的高速缓存行。映射关系表示为:i = j mod m。
对高速缓存访问来说,每个主存地址都可以被视为由三个字段。最低w位指明一个主存块内唯一的字或字节。地址中的其余s位指定2^s个主存块中的一块。高速缓存逻辑把s位解释为s-r位的标签字段和一个r位的行字段。
直接映射技术:实现起来简单且便宜。它的主要缺点是对任何给定块都只有固定的高速缓存位置。因此,如果一个程序反复从两个不同的块中引用的字正好映射到同一行,那么这些块就会不断地被交换进高速缓存,从而降低命中率(抖动)。
降低缺失代价的一种方法是保存被丢弃的内容,使用受害者缓存能进行这种回收。受害者缓存被提出的理由在于减少直接映射缓存高速缓存的冲突缺失,而又不影响其快速的访问时间。受害者缓存是全相连高速缓存,其大小一般为4~16个高速缓存行,位于直接映射的L1高速缓存和下一级存储器之间。
2.全相联映射:全相联映射克服了直接映射的缺点,它允许每个主存块加载到任何高速缓存行。高速缓存控制逻辑只把存储器地址解释为一个标签字段和一个字字段。标签字段唯一标识一个主存块。要确定一个主存块在不在高速缓存中,必须同时检查每个行的标签是否匹配。
当新块被读入高速缓存时,使用全相联映射可以灵活地决定替换那个块。其主要缺点在于需要复杂的电路来并行检查全部高速缓存行的标签。
3.组相联映射:一种折中方案,组内全相连,组外直接映射。它既体现了直接映射的和全相联的优点,又减少了它们的不足。此时,高速缓存由一些组构成,每一组都包含了若干行,k路组相联映射关系如下:
m=v*k
i=j mod v
i:高速缓存组号;
j:主存块号;
m:高速缓存中的行数;
v:组数;
k:每组中的行数;
组相联高速缓存可以在物理上实现为v个全相连的高速缓存,同理,也可实现为k个直接映射高速缓存。
高速缓存大小低于64Kb时,直接映射和2路组相联映射的性能差异非常显著。超过32Kb后,增加高速缓存大小不会带来性能的显著提高。
4.3.4 替换算法
当高速缓存已满,而又有新块要调入时,就必须替换其中已存在的块。对直接映射而言,任何特定块都只有一个可能的块与之呼应,没有其他选择。
对于全相连和组相联技术而言,就需要替换算法。为了达到高速,算法必须在硬件上实现。只讨论最常见的4种。最有效的大概是最近最少使用算法lru:替换组内在高速缓存中最久没有被引用过的块。在2路组相联中,这个算法很容易实现,每行有一个use位。当某行被引用后,其use位置1,而同组中另一行清0。对于全相连高速缓存,实现lru算法也相对容易。高速缓存机制位缓存中全部行维护一个单独的索引列表。当一行被引用时,它被移动到列表的前端。替换时,使用的列表后段的行。由于实现简单,lru是最流行的替换算法。
另一种方法是先进先出fifo算法:替换组内最久的块。fifo很容易实现为循环或循环缓冲技术。
还有一种方法是最不常用lfu算法:替换组内经历引用最少的块。lfu通过在每行关联一个计数器来实现。
4.3.5 写策略
如果高速缓存的该行的某个字被执行了至少一次写操作,那么在调入新块前要把旧块写到主存来更新主存。根据性能和成本之间的权衡,这里需要解决2个问题:首先,可能有多个设备访问主存。此外,当多个处理器连接到同一总线且每个处理器都有自己的本地高速缓存时。
最简单的技术被称为写通:所有的写操作都会施加于主存和高速缓存,以确保主存总是有效的。任何其他处理器--高速缓存都可以监视到主存的传送,以维护自己高速缓存的一致性。该技术的主要缺点在于它会产生大量的主存流量,可能会形成一个瓶颈。
另一种技术是写回:它能最小化主存写操作,更新仅在高速缓存中执行。发生更新时,与行相关联的dirtyh或use位置1。之后当一个块被替换时,当且仅当dirty位为1时,该块写回主存。写回的问题在于部分主存不是最新值,因此,io模块只能通过高速缓存访问。这造成了复杂的电路和潜在的瓶颈。
在总线组织中、有多个设备(通常是处理器)带有高速缓存且共享主存,这会产生新的问题。如果一个高速缓存中的数据被修改了,那么不仅使得主存中相应的字无效,也会使得其他高速缓存中同一个字无效(如果其他高速缓存恰好有相同的字)。即使在写通策略,其他高速缓存夜可能包含无效数据。该问题称为缓存一致性,高速缓存一致性包含如下可能性:
1.写通的总线监视:每个高速缓存控制器监视地址线,以检测其他总线对主存的写操作。如果另一个处理器向共享内存写入的位置在本地高速缓存中也有驻留,那么高速缓存控制器使得该缓存项无效。
2.硬件透明:用额外的硬件确保所有通过高速缓存对主存的更新都反映到全部高速缓存中。
3.不可高速缓存存储器:只有一部分主存被多个处理器共享,这被指定为不可高速缓存的。所有对共享存储器的访问都是高速缓存缺失,因为共享存储器不会复制到高速缓存中。
4.3.6 数据行大小
当一个数据块被取出并放入高速缓存时,不仅仅是所需字,一些相邻字也被取出。当块大小从很小增加到很大时,由于局部性原理,命中率先会升高。但是当块变得更大时,命中率却开始下降,因为使用新获取到信息的概率变得小于重用被替换信息的频率。影响有二;
1.更大的块减少了高速缓存能容纳的块数,块数少导致获取到的数据很快就被覆盖;
2.当数据块变大时,每个额外的字距离请求的字会更远,因此,在不远的将来不太可能被需要;
块大小与命中率之间的关系是复杂的,它取决于特定程序的局部特性,找不到确定的最优值。8~64字节似乎是接近最优的。对于hpc程序而言,64字节和128字节高速缓存行大小是最常用的。
4.3.7 高速缓存的数量
最近多个高速缓存越来越常见,设计问题涉及两个方面:高速缓存的层数以及混合和分离缓存的使用。
多层高速缓存: 随着逻辑密度的增加,让高速缓存与处理器位于同一芯片成为可能:片上高速缓存。相比于通过外部总线访问高速缓存,片上缓存减少了处理器外部总线的活动,因此也就加快了执行速度降低了访问时间,提高了系统整体性能。当被请求的指令或数据在片上高速缓存中被发现时,总线访问被取消。由于处理器内部的的路径较短,与总线长度相比,片上高速缓存访问甚至比零等待状态总线周期还要快得多。此外,在这个访问间,总线可以用来支持其他传输。
包含片上高速缓存会留下一个问题,即是否还需要片外或外部高速缓存。
大多数现代设计都包括片上和外部高速缓存,最简单2级高速缓存:L1和L2。包含L2高速缓存的理由
1.如果没有L2高速缓存,当处理器对一个不存在于L1缓存的主存位置发出访问请求时,处理器就必须通过总线访问dram或rom存储器。
2.如果使用L2 sram高速缓存,则可以经常快速检索到缺失的信息。
多级高速缓存的现代缓存设计有两个特性值得注意。
1.对片外L2高速缓存来说,许多设计没有使用系统总线作为l2高速缓存,而是使用了单独的数据路径,这样就可以减轻系统总线的负担。
2.随着处理器组件的不断缩小,现在许多处理器在芯片上集成了L2高速缓存,以提高性能。
使用多级高速缓存会使所有有关缓存的设计问题复杂化,包括大小、替换算法、写策略。
如果L2缓存与L1缓存的行大小和容量都一样,则其内容或多或少会是L1缓存内容的镜像。
开始的时候,L3高速缓存要通过外部总线访问。最近,大多数微处理器都添加片上L3缓存。
混合式与分离式高速缓存:当片上高速缓存首次出现时,许多设计都有一个缓存组成,用于存储被引用的数据和指令。目前将高速缓存分成两个:一个专门存指令,一个专门存数据。
混合式高速缓存有2个潜在的优势:
1.对给定高速缓存大小来说,混合式高速缓存的命中率高于分离式,因为它能自动平衡取指令和取数据的负载。
2.只需计划和实现一个高速缓存。
目前的趋势是L1上分离高速缓存,在更高层次上使用混合式缓存,尤其是强调指令并行执行和预取被预测未来指令的超标量计算机上。分离式高速缓存设计的主要优点是它消除了指令预取/译码单元和执行单元对高速缓存的争用。这一点对依赖于指令流水线执行的任何设计都是重要的。
4.4 Pentium 4高速缓存结构
问题 | 解决方案 |
外部存储器比系统总线慢 | 添加外部高速缓存 |
处理器速度的提高使得外部总线成为高速缓存访问的瓶颈 | 把外部高速缓存移到片上,操作速度与处理器相同 |
由于芯片空间有限,内部高速缓存相当小 | 添加外部L2高速缓存 |
当指令预取部件和执行单元同时访问高速缓存,则预取部件被阻塞,执行单元访问数据。 | 创建单独的后端总线bsb,其运行速度快于主总线。bsb专门用于l2高速缓存 |
处理器速度的提高使得外部总线成为访问L2高速缓存的瓶颈。 | 创建单独的后端总线bsb,其运行速度快于主总线。bsb专门用于L2高速缓存 |
某些应用程序处理大量数据库,必须能快速访问大量数据。片上高速缓存太小。 | 添加外部L3高速缓存 |
Pentium 4的处理器核心由4个部分组成:
1.预取/译码单元:按序从L2高速缓存中取出程序指令,把它们译码为一系列微操作,并把结果存放在L1指令高速缓存中。
2.乱序执行逻辑:根据数据依赖性与资源可用性调度微操作的执行。
3.执行单元:从L1数据高速缓存中取得数据,并将结果临时存放在寄存器中。
4.存储器子系统:包含了L2、L3高速缓存以及系统总线,用于在L1和L2高速缓存出现缓存缺失时访问主存,以及访问系统Io资源。
Pentium使用简单的,定长微操作可以利用超标量流水技术和调度技术来提高性能。
附录
二级存储的特性
主存-高速缓存 | 虚拟存储器(分页) | 磁盘缓存 | |
典型的访问时间之比 | 5:1 | 10^6:1 | 10^6:1 |
存储器管理系统 | 由特殊硬件实现 | 硬件和系统软件的组合 | 系统软件 |
典型的块大小或页 | 4~128字节 | 64~4096字节 | 64~4096字节 |
处理器对二级的访问 | 直接访问 | 间接访问 | 间接访问 |
局部性
局部性原理是有意义的,原因如下:
程序执行是顺序的,除了分支和调用指令。
长时间不间断的过程调用序列后跟相应的返回序列是少见的。一个程序仍然会被限制在一个相当窄的过程调用深度的窗口。
大多数迭代结构是由数量相对较少的指令重复多次构成的。
许多计算设计对数据结构的处理,比如数组或记录序列。
空间局部性是指涉及的内存地址具有簇聚倾向。这反映了处理器按序访问指令的趋势。空间位置还反映程序按序访问数据地址的趋势。
时间局部性是指处理器访问最近使用过的内存地址的倾向。
传统上,通过把最近使用的指令和数据保存到高速缓存中已使用缓存层次结构来利用时间局部性。空间局部性则通过使用更大的高速缓存块以及把预取机制合并到缓存控制逻辑来利用。
不论主存大小是多少,相当小的高速都会产生高于0.75的命中率。高速缓存大小在1k~128K字节范围一般就足够了。