【2021/4/12修订】【梳理】计算机组成与设计 第5章 存储的层次结构(docx)

配套教材:
Computer Organization and Design: The Hardware / Software Interface (5th Edition)
这是专业必修课《计算机组成原理》的复习指引。建议将本复习指导与博客中的《简明操作系统原理》配合复习。
需要掌握的概念在文档中以蓝色标识,并用可读性更好的字体显示 Linux 命令和代码。代码部分语法高亮。
计算机组成原理不是语言课,本复习指导对用到的编程语言的语法的讲解也不会很细致。如果不知道代码中的一些关键字、指令或函数的具体用法,你应当自行查找相关资料。


第五章 存储的层次性

第一节 缓存

第二节 纠错

第三节 虚拟机与虚拟化

第四节 缓存一致性

注意

链接:https://pan.baidu.com/s/1E8AC-bCJxfBag6SXI3LyiA
提取码:0000


第五章 存储的层次性

第一节 缓存
计算机存储系统依托的基本原理是局部性原理(principle of locality)。它包括:
时间局部性(temporal locality):如果一项数据被访问,那么它在接下来的一段时间内很可能再次被访问。
典例:循环。
空间局部性(spatial locality):如果一项数据被访问,那么它附近的数据在接下来的一段时间内很可能也被访问。
典例:顺序执行指令、顺序访问一个数组。
局部性原理告诉我们:在一段时间内,程序一般只会访问地址空间内的较少一部分的内容。

在第一章我们已经提到,程序员们总是渴望又快又大又便宜的存储。但高速存储(如:缓存)的成本巨大,大容量的存储(如:硬盘)虽然花费相对较低,但性能远远不足。容量和性能往往又不能兼顾。一个缓和这些矛盾的方法是:设计不同层次的存储。
计算机的存储系统是分层的,即具有层次性(hierarchy)。存储层次从高层到低层分别是:寄存器、缓存、内存和外存(HDD / SSD)。处于更高层次的存储器,速度更快、价格更高、容量更小;处于更高层次的存储器,速度更慢、价格更低、容量更大。
存储分层与局部性原理切合,能将存储系统的性能充分发挥出来。
高层的存储器存储的数据总是低层存储器存储的数据的子集。数据只能从低层次传入相邻的高层次。

在计算机存储器中,数据一般是按照行(line)或块(block)作为最小单位来整体存储的。如果按字节读写而不是一次性按照一个块读写,那么没有用在数据传输本身的时间(包括定位等)的占比就会更多,总体而言数据的传输速率就会变得很慢。这一点在《简明操作系统原理》(《操作系统原理 知识梳理》)中已经反复强调过了。

缓存等较快的存储器有一个指标叫做命中率(hit rate),是指能够在存储器中直接找到的数据占所有需要访问的数据的比值。相应地,也有缺失率(miss rate)。假如命中率较高,那么在速度较快的存储器中就能直接找到需要的数据,于是无需重新在速度较慢的存储器中搜索,也就意味着性能较高。命中时间(hit time),是指访问处于较快层次的存储器的用时。这个用时不但包括访问时间本身,还包括确定一次访问是命中还是未命中的时间。未命中惩罚(miss penalty,缺失惩罚)则是在较高层级的存储未命中后,需要重新从较低层级的存储中取得所需数据需要的时间,包括访问数据所在块的耗时、在不同层级存储之间传输耗时、将需要的数据重新放入较高层级的存储器的耗时,以及将数据传送给请求者的耗时。
现在,CPU的缓存命中率往往能高于95 %。

静态随机访问存储器(Static random access memory,SRAM)是一种存储阵列,具有单个或多个访问端口。SRAM对任何位置的数据进行同种操作(读或写)的用时相同,但读取和写入速率可能是不同的。SRAM不需要刷新(refresh),所以访问时间可以做到接近CPU的一个周期。SRAM的一个bit通常需要6或8个晶体管(也可以有10管乃至更多)。只要SRAM保持通电(功率非常小),数据就不会丢失。
很久以前,SRAM与CPU是分开的;但随着制程的进步,SRAM很快就被集成到了CPU里。

动态随机访问存储器(Dynamic random access memory,DRAM)使用电容来存储数据,每个bit还需要一个晶体管(MOS管)来控制读写。DRAM的存储密度远高于SRAM,但由于数据是用电容中存储的电荷来表示的,因此DRAM必须周期性刷新,防止电容中的电荷流失。这也是DRAM中“Dynamic”一词的由来。
刷新是通过读取存储的数据并重新写入来实现的。电容中的电荷大约只能维持几毫秒。我们不能以字节为单位来依次读取数据并刷新,因为这样全部时间就会耗费在刷新上,而无法访问数据。DRAM采用两级译码结构,允许在读周期后立刻跟一个写周期来刷新一整行。
DRAM会缓存被频繁访问的行,这大大提升了访问速率。如果将DRAM的位宽做得更宽,也可以提升性能。

为了与CPU更好地配合,DRAM也受时钟控制,这种DRAM称为同步DRAM(Synchronous DRAM,SDRAM)。这就消除了CPU与内存同步的时间。
后来又出现了DDR SDRAM。DDR即Double Data Rate(双倍传输速率)。DDR SDRAM在时钟的上升沿和下降沿都能进行一次传输,速率比初代SDRAM直接翻倍。

DRAM不但按行来组织结构,还被分成多个bank。每个bank具有许多行,并都具有自己的缓存。发送一个PRE(precharge,预充电)信号可以开启或关闭一个bank。行地址与ACT(activate,激活)信号发送,使得行被传送到缓存中。于是,可以向多个bank同时发送地址,这些bank同时进行读写。这种技术称为地址交叉(地址交错,address interleaving)。

手机和平板电脑上,DRAM颗粒常与CPU封装在一起(PoP,Package on a Package)或直接焊接在主板上;而台式或笔记本计算机中,DRAM颗粒被做在双列直插式存储模块(dual inline memory module,DIMM)上,也就是俗称的内存条。

在x86架构的PC、工作站和服务器上,CPU和内存之间的每个通道(Channel)的位宽为64-bit。假设某台式机具有双通道DDR4内存,并且等效频率为3200 MHz(实际时钟为1600 MHz),那么该计算机的内存带宽就达到2×64-bit×3200 MHz = 51.2 GB/s(1000进制),即理论上每秒能传输51.2 GB的数据。工作站和服务器常常能支持四通道的内存,较为高端的服务器可以达到六通道和八通道。
单个内存颗粒的位宽仅有4-bit、8-bit或16-bit,个别也有32-bit的。因此,必须把多个颗粒并联起来,组成一个位宽为64-bit的数据集合,才可以和CPU互连。总位宽达到64-bit的一组颗粒称为一个rank。如果内存条支持错误校验码(Error-correcting code,ECC),那么会多出额外的颗粒,每个rank的总位宽就变为72-bit。内存条的标签上会标出诸如1R×4、2R×8这种标识,xR×y的x和y分别表示这根内存条的rank数和单个颗粒的位宽。
需要注意的是,平台对rank的数量是有限制的。插在主板上的内存条的rank总数不能超过平台限制。

闪存(Flash memory)是电擦写可编程只读存储器(electrically erasable programmable read-only memory,EEPROM)的一种。DRAM的寿命非常长,但EEPROM的寿命是很有限的。现在的存储设备会将已损坏或磨损较多的闪存块重映射(remap),即用正常的备用块代替。Flash控制器中还实现了许多能平衡各个块之间的寿命耗损程度的算法。
有的SSD会向用户报告其剩余寿命,也有不少软件可以查看相关的监测数据。不过,寿命只是参考值。在大多数情况下,SSD的主控芯片报告闪存寿命耗尽后,这块盘往往还能运行很久;但也有在主控芯片报告闪存寿命终结之前SSD就猝死的情况。总的来说,还是看运气。

关于机械硬盘,请参阅《简明操作系统原理》。

第四章提到了数据通路中的内存,包括指令内存和数据内存。在这里,我们揭晓它们的正式名称:高速缓存(cache),简称缓存。前面讲过,当缓存中未找到需要的数据时,就需要到更慢的存储器中重新检索,并将其放入缓存。我们如何得知一项数据是否在缓存中呢?如果将缓存做成直接映射(direct-mapped)缓存,就很容易根据需要访问的地址确定是否在缓存中了。几乎所有的直接映射缓存都按照“块地址 % 缓存块数”的方式来决定内存中不同位置的数据在缓存中存储的位置。缓存的块数为2的整数次方块时,取模可以被优化成直接截取低若干位。
当然,缓存的容量是远远小于内存的,所以会有多个内存地址的数据先后被放入缓存中的同一个位置(放入新数据后,原有的数据会被覆盖)。
除了存储数据的区域,缓存还有额外的位置作为标签(tag)。标签存放了内存地址的高位,这个值描述了缓存中保存的数据来自内存中的哪个位置。地址低位是不需要写入标签的,这些低位可以作为偏移,在缓存中对需要的那部分数据直接进行定位。
缓存中还具有有效位,刻画该块的数据是否有效。若有效位为无效,则这个块具有的其它记录都无意义。在系统刚启动时,缓存的所有有效位都被记为无效,因为此时还未有任何数据保存在缓存中。
缓存容量,指的是实际能用于存储数据的那部分容量,不包括标签和有效位占用的容量。

缓存的块大小不能太大也不能太小。
如果块大小过大,由于缓存的容量不大,很快就会面临有数据需要替换的时刻。这时候,可能一个块中的许多数据还没被重新访问过多少次,就被连同整个块一起替换了,这就导致了命中率不升反降。而且,块过大也会令未命中惩罚上升,因为将新数据放入缓存的耗时多了(整个块一起放入)。此外,过大的块内的空间局部性也会降低,导致性能难以提升。
如果块大小过小,则没有充分利用空间局部性:块附近的信息不久可能也会被访问,但并没有被调入缓存内。
下图是块大小与缺失率的关系折线图。其它条件不变,缓存容量越大,缺失率越低。如果块大小适中,就能最大程度发挥空间局部性的优势,大多数时候都能将命中率维持在高水平。

为了缩短CPU的闲置时间,许多CPU都大规模应用了这样一种技术(early restart):不会在缓存读完一整块时才返回,而是在读完请求的字以后就返回:程序一边执行,存储系统一边继续读取。对于指令,这种方法对性能提升非常奏效:指令一般都是顺序执行的(即使有循环、跳转,在跳至其它位置以后往往还会顺序执行一段时间再进行下一次跳转),从指令缓存(instruction cache,I-cache,I ) 中 读 到 一 条 指 令 之 后 , 就 可 以 返 回 并 令 C P U 继 续 执 行 ; 同 时 , 下 一 条 指 令 由 存 储 系 统 继 续 负 责 读 取 , 而 后 继 续 传 回 给 C P U 。 对 于 数 据 缓 存 ( d a t a c a c h e , D − c a c h e , D )中读到一条指令之后,就可以返回并令CPU继续执行;同时,下一条指令由存储系统继续负责读取,而后继续传回给CPU。对于数据缓存(data cache,D-cache,D CPUCPU

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值