cache合并优质参考Word文档下载推荐.docx
《cache合并优质参考Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《cache合并优质参考Word文档下载推荐.docx(13页珍藏版)》请在冰豆网上搜索。
Q1:
一个块,会放在哪里?
直接映射:
每个块在Cache中只能出现在唯一位置上,映射方法:
(块地址)mod(Cache中的块数)
全相联映射:
一个块可以放到cache中任何一个地方。
组相联映射:
一个块放到一个受限的组里。
一个块首先映射到到一个组中,可以放到组中任何一个块中。
组通常用为选择方式确定:
(块地址)mod(cache中的组数)
如果一个组里有n块,这种映射方法称之为n路组向联。
直接映射是一个简单的1路组相联。
全相联是只有1组的m路组向联映射。
Q2:
怎样找到cache中的块?
Cache地址分为块地址与偏移地址;
块地址又分为标志字段与索引字段。
偏移地址用来选择块中所需要的数据;
索引字段用来选择组,通过标志字段来判断是否发生命中,无需判断块内偏移与索引字段。
增加相联度会增加组内的块数,组数减少导致索引段减少,标识字段增加,最后变成全相联,不存在索引字段。
Q3:
没有命中,块怎样替换?
直接映射法:
直接替换没用命中的检查的块。
全相联或组相联,需要多个块做出选择。
大容量时3中方法区别不大,小容量时LRU最优:
随机替换(Random):
利用伪随机数块号,尤其适用于硬件调试。
最近最少使用(LRU):
记录块的访问次数,利用历史信息替换掉最长时间没有使用的cache块。
先进先出(FIFO)。
Q4:
写操作时cache会发生什么?
一般来说,CPU需要等待读操作完成,不需要等待写操作完成,且块标志与数据同时读出,舍弃没有命中的信息可提高速率,嵌入式系统不允许无用工作。
对写操作不能进行如此优化,因为只有标识为有效时,块才能被修改。
2中基本的写策略:
写直达(writethrough):
信息同时写入cache和更低一层的存储器的块中。
易实现,写直达方法中读操作缺失发生时cache始终是干净的,因此不需要对低层存储器进行写操作,常与不按写分配(no-writeallocate)配合。
写回法(writeback):
信息只写入cache。
只有cache中块被替换,信息才会写回到主存中。
写操作与cache速度一致,且一个块一次写入仅仅需要对下层存储器的一次写操作,因此需要较小的带宽,可用于多处理器的服务器系统。
常与写分配(writeallocate)配合。
写操作缺失时,通常策略如下:
写分配(writeallocate)内存读到cache,执行命中前面写命中时的操作。
与读缺失类似。
不按写分配(no-writeallocate),仅修改低层存储器中的该块,不将该块写入cache中,直到程序要读一个块时,该块才被取到cache中。
Cache可以提供指令与数据,但存在瓶颈,例如同时执行一条载入指令与存储指令,单独的cache会产生资源冲突,产生停顿。
最简单的方法是将cache划分为指令cache与数据cache。
指令cache比数据cache有更低的缺失率,但分立的指令cache与数据cache缺失率之和比相同容量的cache更大。
5.3Cache性能
5.3.1平均存储器访问时间
指令数可以用来评价CPU的性能,缺失率可以评价存储器层次结构的性能,但也会产生误导,可用平均存储器访问时间来评定:
虽然降低最小平均存储器访问时间是一个合理的目标,但是最终目标时降低CPU执行时间,两者时有区别的。
例如在2路组相联情况下,虽然缺失率与平局存储器访问时间较低,但进行组内多路选择时CPU时钟周期也会增加,导致CPU执行时间变长。
一般观点,把命中时钟周期数包含到CPU执行时钟周期数种。
Cache的行为会对较低CPI与较快时钟频率的CPU产生双重影响:
1.CPI较低时,cache缺失时钟数会对CPU时间产生较大影响。
2.计算CPI(cache缺失情况)时,cache缺失代价用缺失时花费的CPU时钟周期数来度量。
因此,对于存储器层次结构相同的计算机,CPU频率越高,每次缺失就需要更多的时钟周期数,因此CPI花费在存储器部分的周期就较多。
5.3.2缺失代价与乱序执行处理器
乱序执行(out-of-orderexecution):
CPU允许将多条指令不按程序规定的顺序分开发送给各相应电路单元处理的技术。
这样将根据各电路单元的状态和各指令能否提前执行的具体情况分析后,将能提前执行的指令立即发送给相应电路。
重新定义存储器停顿周期:
一般确定延迟时间的方式有3种:
从存储器指令进入指令窗口的时刻算起;
或是从地址产生的时刻算起;
或是从指令实际被送到存储器的时刻算起。
只要使用一致,任何一种方式都行。
1.索引长度确定:
2.平均存储器访问时间:
3.存储器停顿周期:
4.CPU执行时间:
为平均每条指令的访存次数
5.对于乱序执行处理器的平均每条指令的停顿周期数:
5.4降低Cache缺失代价
5.4.1多级cache
此为降低缺失代价中最重要的方法。
在原cache存储器之间加一级cache,第一级cache可以小到足以与快速CPU运行时钟相匹配,第二级cache可以大到足以捕捉到对主存的大多数访问,从而减少缺失代价。
缺失代价重新定义为:
其中,第一级cache缺失代价为:
局部缺失率:
这一级cache的缺失数与这一级cache的访存总数;
第一级cache中,等于
;
第二级中,等于
。
全局缺失率:
这一级cache的缺失数与CPU产生的访存总数;
第一级中,等于
第二级局部缺失率比较大,因为第一级cache存储数据是最易命中的,所以全局缺失率是一个更有用的度量方法。
此时每条指令的缺失次数重新提出:
首先,可以选择价高相联度来降低第二级缺失率,可降低缺失代价。
其次,多级包含的存储器结构便于检查I/O口与cache之间的一致性,但缺点是,当二级cache发生缺失时,要保证与之对应的一级cache块无效,从而会导致一级cache缺失率略微升高。
当二级cache只比一级cache大一点时,可以采用多级互斥(multilevelexclusion)。
一级cache缺失时只会导致两者之间进行对应的块互换,而不是用第二级cache中的块去替换一级cache中的块,防止二级cache空间浪费。
5.4.2关键字优先和提前启动
给予CPU在某一个时刻只需要块中的一个字,不必要等全部块装入便可启动CPU,具体如下:
关键字优先:
首先向存储器请求缺失的字,然后它一旦到达便把它发给CPU,使得CPU在装入其他字的同时能够继续执行其他指令。
提前重启动:
以正常顺序获取字,块中所需字一旦到达,立即发给CPU,使得CPU继续执行。
通常这些技术适用于大cache块设计,否则收益甚微。
5.4.3确定读缺失对写的优先级
例如写缓存区中可能包含读缺失时所需要的更新数据,此时最简单的方法是读缺失等待、直到写缓存为空为止。
另一种方案时读缺失时查看缓存的内容,如果没有冲突且存储器系统可以访问,就让读缺失继续。
一般后者多用。
写回法的cache中,处理器的写开销也可以降低。
当读缺失发生时,脏块将被代替。
我们可以把脏块复制到一个缓存区后就读下一层的存储器,而不是先把脏块写入下一层存储器,然后再对下一层存储器进行读操作。
这样可以很快的完成读操作。
5.4.4合并缓冲区
所有的存储都必须放到较低一级的存储层次上,因此写直达的cache也依靠写缓冲。
写缓冲为空时,从CPU角度来说,将被替换掉的数据和地址都放到写缓冲中,写操作就结束;
写缓冲区将数据写回内存时,CPU可继续工作。
如果写缓冲里还有其他数据被修改过,检查地址,看新数据地址是否与缓冲区的某一项地址相匹配。
如果匹配,新数据合并到该项中,此过程曾为“写合并”。
写缓冲满、且地址不能匹配,cache与CPU必须等待,直到缓冲区空出一个项。
因为一次写多个字比一次写一个字速度更快。
5.4.5牺牲cache
保存被替换掉的块,以便下一次使用。
该循环方案是在cache与它的替换路径之间增加小容量的全相联cache。
这个牺牲cache(victimcache)之包含cache中因为缺失而被替换出的块,然后发生缺失时,在访问下层存储器之前,先检查牺牲块,看其中是否包含所需数据。
5.5降低Cache缺失率
3种缺失模型:
a.强制缺失:
对一个块的第一次访问一定不在cache中,所以该块必须调入到cache中。
可以增加块大小来减少该缺失,但是又会导致其他种类的缺失。
b.容量缺失:
如果cache容纳不了一个程序执行所需的所有块,将会发生容量缺失(还会有强制缺失),某些块被抛弃随后再被调入。
只能增大cache容量减少该缺失,但如果上层存储器空间很小,很多时间会花费在层次结构两层之间搬运数据上,称之为存储器层次结构的抖动现象。
因此,机器速度接近于较低层。
c.冲突缺失:
如果块替换策略时组相联或直接映射的,并且有太多的块被映射到同一组中,则某一个块被抛弃,之后重新调入,这时就发生了冲突缺失(还会有强制缺失与容量缺失)。
全相联可以避免所有的冲突缺失,但是硬件昂贵,同时可能会使处理器处理时钟变慢。
但是三种模型存在矛盾、局限的。
改变cache容量,则缺失可能会由容量缺失变为冲突缺失。
增加组相联度会使降低缺失率,与增加块容量降低缺失率的强制缺失也是矛盾的。
所以,要寻求平衡点。
5.4.1增加块容量
此为最简单的方法。
但是它减少了块数,更大的块可能导致冲突缺失,如果cache容量较小,可能会导致容量缺失。
块容量的选择取决于较低层存储器的延迟和带宽:
高延迟和高带宽存储器尽量使得块容量大一些,因为此时每次缺失时cache可以获得更多的字节,而缺失代价只有少量的增加。
相反,低延迟、低带宽希望块容量小一些,因为较大的块并不能节省很多时间。
例如,小容量块缺失的代价的两倍可能接近于两倍容量块一次缺失的代价,块容量小,块数量多,可能会减少冲突缺失。
5.4.2增加cache容量
能减少容量缺失,但是会时cache命中时间增加,开销增大。
5.4.3增加相联度
根据缺失率随相联度改善的的情况,得到2个一般结论:
a.8路组相联和相同容量的全相联cache在降低cache缺失率方面同样有效,因为容量缺失时用全相联cache来计算的。
b.容量为N的直接映射同容量为N/2的2路组相联cache几乎有相同的缺失率。
所以cache容量一般少于128KB。
但是,增加相联度会导致命中时间增加;
增加块容量会降低缺失率,但也增加了缺失代价。
5.4.4路预测与伪相联cache
路预测:
在cache中设置预测位,来预测下一次cache访问中可能会在组中用到的路或块。
该方式需要提前利用多路选择器来选择即将被访问的块,只需要在一个时钟周期内比较一个简单的标志位。
如果缺失,在检查其他块是否匹配。
该方案可以在降低冲突缺失的同时,保证cache的命中速度。
伪相联:
命中时,该过程同直接映射的cache访问过程一致。
缺失时,在访问下一层存储器之前,通过检查另一个cache项确当是否在那里命中。
最简单的方法是对索引字段中的最高位进行反转来发现“伪组”中的另一块。
第一个缺点,如果cache快的命中时间变为伪相联cache中长命中时间,性能会下降,因此需要指出每个组中哪一个时快时间命中,哪一个时慢时间命中。
最简单的方法时令高位的块为快的块,通过交换块中内容进行切换。
第二个缺点是:
检查另一个cache项有时间开销。
5.4.5编译优化
不需要硬件改动,保证程序代码正确性的前提下,对软件进行优化。
可分为指令缺失性能改善与数据缺失性能改善。
例如,对指令重新编排,对块进行排序,利用分块算法,改进数据的空间和时间局部性来减少缺失率。
5.6通过并行减低缺失率或缺失代价
5.6.1用非阻塞cache减少缺失停顿
对于乱序执行的流水线机器,CPU在等待数据cache返回缺失数据时,可以继续从指令cache中取指令,即缺失时仍命中。
如果能重叠多个缺失,可进一步降低有效缺失代价。
缺点是增加了cache控制器的复杂性。
通常,乱序执行的CPU如果能在二级cache中命中,则能隐藏一级数据cache的缺失代价,但不能隐藏二级cache缺失所带来的缺失代价。
5.6.2指令和数据硬件预取
该方法为:
在处理器访问指令与数据之前,将它们预取到cache或者可以比内存访问速度更快的外部缓冲区中。
指令预取通常在cache外的硬件中完成。
一般情况下,微处理器在缺失时取2个块:
被请求的块与其后紧挨着的块。
被请求的块装入到指令cache中,预取的块被装入到指令流缓冲区中。
如果被请求的块在指令缓冲区中找到,则原cache被取消,块从流缓冲区中被读出,然后下一个预取请求被发出。
数据访问类似。
该技术依赖于存储器贷款,但是如果它与命令缺失相冲突,实际上会降低性能。
5.6.3编译控制预取
利用编译插入预取指令,提起发出数据请求,主要分为两种方法:
a.寄存器预取:
把值预取到寄存器中。
b.cache预取:
把数据预取到cache中,并不放到寄存器中。
两者都是故障性或者非故障性的,区别在于地址会不会引起虚拟地址错误和保护冲突异常。
非故障性指令通常在导致异常时转化为空操作。
预取数据的同时,保证处理器能继续工作,预取才有意义,即等待预取数据同时,cache可继续提供指令和数据。
编译控制预取目标是是执行与预取数据重叠进行的,优化时循环是主要目标。
如果缺失代价很小,编译器只需要把循环展开一次或者两次,如果过大,需要使用软件流水线或者多次展开循环来为以后的循环预取数据。
然而生成预取指令也会带来一个指令的开销,所以要谨慎使用保证这些开销不会超过收益。
硬件和软件预取技术主要是根据对cache需求的估计,利用更高的存储器带宽来提高性能,虽然对于功耗很敏感的嵌入式系统没有多大意义,但是对于桌面处理器和服务器却很有用。
预取的成功不仅能降低缺失代价,如果预取指令出现的足够早,还能降低缺失率。
5.7减少命中时间
5.7.1小而简单的cache
Cache命中时间最耗时的是按地址的索引字段去读标志存储器,然后再与地址比较。
较小的硬件速度快,有助于减少命中时间。
Cache可以小到与处理器放在同一个芯片中,避免片外时间代价。
采用直接映射cache可以是标志检查与数据传输重叠,有助于减少命中时间。
对于第二级cache,为了提高标志位检查速度的同时,提供了一个大容量的独立存储器芯片,采取折中方案:
将标志放在片内,而将数据放在片外。
5.7.2在cache索引中避免地址变换(虚拟cache)
但是容量小、结构简单的cache也避免不了从CPU的虚拟地址到内存物理地址的变换。
但是命中相对于缺失是经常性时间,“加快经常性事件速度”的建议告诉我们对cache使用虚拟地址。
称该类cache为虚拟cache。
但一个问题是,检索cache与标志字段比较时,应该用虚拟地址还是物理地址?
另一个问题,完全采用虚拟地址免除了cache命中时的地址变换时间,为什么设计者不全用虚拟地址的cache呢?
第一个原因是保护问题。
虚拟地址变换为物理地址时,必须进行页级保护检查。
一个解决方法是,当发生缺失时,将TLB中的信息复制并增加一个字段,每次访问虚拟地址cache时只要检查该字段即可。
第二个原因是每次进程切换时,虚拟地址对于不同的物理地址,这要求刷新cache。
但刷新cache会对缺失率造成影响。
一种解决方法是增加cache地址标志字段的宽度,即加上一个进程标志(PID)。
操作系统对每个进程分配PID,来确定cache中的数据是否属于该程序。
第三个原因是对于同一个物理地址,操作系统和用户程序可能使用两个不同的虚拟地址。
双重地址称为别名地址,将会导致同一个数据在虚拟cache中存在两个副本,如果其中一个被修改了,另一个值将会是错误的。
一种解决方法是用别名消去的硬件技术来保证每一个cache块有一个唯一的物理地址。
发生缺失时检查所有组的块,保证没有与已经取得的数据的物理地址冲突,否则使之无效。
另一种软件法是使所有别名地址的后18位相同(Sun微系统公司的UNIX)。
这种限制称为页着色,适用于虚拟存储采用简单组相联映射的情况:
采用直接映射的cache,若容量小于256KB(2^18),则不可能产生双重地址。
从cache角度看,当虚拟地址与物理地址最后几位相同时,页着色页增加了页内偏移。
第四个也是最后一个原因是I/O也涉及到虚拟地址。
I/O主要使用物理地址,因此需要将物理地址映射为虚拟地址以便与虚拟cache进行交互。
充分利用虚拟cache与物理cache的一种方法是使用页偏移不受地址变换影响的部分,去索引cache。
当利用这索引去读cache时,地址中虚拟地址被转换,标志字段匹配使用物理地址。
采用多路组相联既可以保证索引位较少从而能够从地址的物理部分获得,又可以使cache的容量较大。
5.7.3流水线化cache访问
流水线化访问cache是一级cache命中的有效延时分散到了几个时钟周期,提供了较短的周期时间与较长的命中时间。
这种方法实际增加了指令的带宽,并非降低了cache命中的实际延迟
5.7.4跟踪cache
对每个周期4条以上的指令级并行的一个挑战是每个周期是否能够提供足够相互无关的指令。
跟踪cache方法,不是根据空间局部性将指令限制在一个静态的cache块中,而是寻找动态指令序列,包括要执行的分支程序。
缺点是指令cache中相同的指令需要存储多次。
具有不同选择的条件分支导致相同的指令成为不同跟踪的组成部分,每一份副本在cache中都占据了空间。
5.9存储器技术
DRAM:
动态RAM。
(1)一般桌面处理器或是服务器内存都是DRAM组成。
(2)随着DRAM容量增大,地址线数目也相应增加,导致地址线封装成本增加。
解决方法是采用多路复用技术,一个地址分别在行选通和列选通的情况下分2次传输,节省一半的地址总线。
(3)存储中只用一个晶体管存储一位信息,需要周期刷新防止信息丢失。
幸运的是,一行中所有位在读取这一行时可以同时被刷新。
(4)刷新所需要的时间为访问DRAM内容所需时间的总和,由于DRAM中的存储矩阵是一个平方的概念,所以所需步数为DRAM容量的平方根。
设计者力求存储器刷新时间小于存储器访问总时间的5%。
SDRAM:
同步(synchronous)DRAM。
传统DRAM和存储器控制器之间是异步接口,与控制器同步会增加每次数据传输的开销,解决方法是在DRAM接口中增加一个时钟信号,使得重复的传输不必承担这一开销。
DDR:
双倍数据速率DRAM。
DRAM在时钟的上升沿与下降沿同时传输数据,倍增峰值速率。
只需要少量的逻辑电路使得带宽大大提高,应用范围广。
SRAM:
静态(static)RAM。
(1)通常用6个晶体管来存储一位信息,防止在读取时被破坏。
(2)嵌入式设备会经常处于低能耗或者待机状态,SRAM只需要很小的电流就能保持信息不丢失。
(3)SRAM强调的是容量和速度,地址线无需复用,同等工艺下容量比DRAM小4到8倍。
(4)一般用于CPU的一级缓存(cache)、二级缓存中。
ROM:
只读存储器。
具有持久性与非写入特性,断电后信息不丢失,如计算机启动用的BIOS芯片。
存取速度很低(较RAM而言),且不能改写。
E2PROM:
带电可擦写可编程ROM。
其可通过高于普通电压的作用来擦除和重编程(重写)。
在一个EEPROM中,当计算机在使用的时候可频繁地反复编程,因此EEPROM的寿命是一个很重要的设计考虑参数。
FLASH:
闪存。
它结合了ROM和RAM的长处,不仅可擦除可编程(EEPROM),还可以快速读取数据,断电不丢失。
近年来Flash代替了ROM(EPROM)——过去20年嵌入式系统一直使用作为存储设备,用作存储Bootloader以及操作系统或者程序代码,或者直接当硬盘使用(U盘)。
RAMBUS:
新的DRAM接口。
(1)在DRAM与CPU之间做了进一步的优化,定义了新的接口,使单块芯片像一个存储系统而不是存储设备。
(2)RAMBUS只改善了数据传输带宽,并没有减少cache系统中得到的一个字节前的延迟,且芯片体积大、性价比差,被DDR逐渐击败。
5.10虚拟存储器
5.10.1基础知识
(1)利用部分内存空间实现内存共享,减少系统大量的地址空间开销;
(2)能减少程序启动时间,因为程序运行之前没有必要把所有代码和数据都载入内存;
(3)可解决程序访问所需内存大于物理内存时的问题,实现自动管理存储器层次结构。
目前两级虚拟存储器由DRAM和磁盘存储器组成。
虚拟内存的几个一般性概念与cache层次概念是类似的,例如分页与分段都是一种分块方式,页故障与地址故障都是指缺失。
还有以下不同:
·
cache缺失主要有硬件进行替换操作,虚拟存储器主要由操作系统控制。
处理器的地址大小决定了虚拟存储器的大小,但和cache大小无关。
辅存(二级存储器)作为主存的下一级后备存储器,还可以用于文件系统,文件系统通常不是地址空间的一部分,并占据了辅存的大部分空间。
虚拟存储器分为两类,一类是使用固定大小的分块,成为页;
另一类使用可变长度的分块,称之为段。
页大小在4k~64k之间,段大小可以变化。
各种机器支持的段最大范围从64k~4G不等。
5.10.2关于虚拟存储器层次结构的四个问题
一个块可以放到内存的什么位置?
虚拟存储器缺失后需要读取磁盘,因此缺失代价非常高。
所以设计者一般要避免缺失代价过高而选择较低的缺失率。
因此,操作系统允许将块放在内存的任意位置。
类似,该策略可以称之为全相联。
Q2:
如何在内存中查找一个快?
页式和段式都依赖于一个按也好或段号的数据结构,通常采用页表的形式。
页表的大小为虚拟地址空间的页数。
例如虚拟地址为32位,页大小4KB,页表的每项位4Bytes,那么页表的大小为(2^32/2^12)*12=2^22Bytes,即4MB。
为使该数据结构尽量小,一些机器中采用一个虚拟地址的散列函数使得该数据结构的大小仅为内存