2.2 Cache的组成结构

2.2 Cache的组成结构

由上文所述,在一个Cache中包含多行多列,存在若干类组成方式。在处理器体系结构的历史上,曾出现过更多的的组成结构,最后剩余下来的是我们耳熟能详的Set-Associative组成结构。这种结构在现代处理器微架构中得到了大规模普及。

在介绍Set-Associative组成结构之前,我们简单回顾另外一种Cache组成结构,Sector Buffer方式[23]。假定在一个微架构中,Cache大小为16KB,使用Sector Buffer方式时,这个16KB被分解为16个1KB大小的Sector,CPU可以同时查找这16个Sector。

当CPU访问的数据不在这16个Sector中命中时,将首先进行Sector淘汰操作,在获得一个新的Sector后,将即将需要访问的64B数据填入这个Sector。如果CPU访问的数据命中了某个Sector,但是数据并不包含在Sector时,将相应的数据继续读到这个Sector中。采用这种方法时,Cache的划分粒度较为粗略,对程序的局部性的要求过高。Cache的整体命中率不如采用Set-Associative的组成方式[23]。

在狭义Cache的设计中,这种方法已经不在使用。但是这种方法依然没有完全失效。处理器体系结构是尺有所短,寸有所长。在一些广义Cache的设计中,Sector Buffer方式依然是一种行之有效的Buffer管理策略。有很多程序员仍在不自觉地使用这种方式。这种不自觉的行为有时是危险的,太多不自觉的存在有时会使人忘记了最基础的知识。

我曾经逐行阅读过一些工作了很多年的工程师的Verilog代码,在这些代码中使用了一些算法,这些算法我总感觉似曾相识,却已物是人非。他们采用的算法实际上有许多经典的实现方式,已经没有太多争论,甚至被列入了教科书中。有些工程师却忘记了这些如教科书般的经典,可能甚至没有仔细阅读过这些书籍,在原本较为完美的实现中填入蛇足。更为糟糕的是,一些应该存在的部件被他们轻易的忽略了。

有时间温故这些经典书籍是一件很幸运的事情。我手边常备着A Quantitative Approach和The Art of Computer Programming这些书籍,茶余饭后翻着,总能在这些书籍中得到一些新的体会。时间总是有的。很多人一直在抱怨着工作的忙碌,没有空余,虽然他们从未试图去挤时间的海绵,总是反复做着相同的事情。多次反复最有可能的结果是熟能生巧而为匠,却很难在这样近乎机械的重复中出现灵光一现的机枢。这些机枢可能发生在你多读了几行经文,或受其他领域的间接影响,也许并不是能够出现在日常工作的简单重复之上。

写作时回忆SectorBuffer机制时写下了这些文字。在现代处理器中,Cache Block的组成方式大多都采用了Set-Associative方式。与Set-Associative方式相关的Cache Block组成方式还有Direct Mapped和Fully-Associative两种机制。Direct Mapped和Fully-Associative也可以被认为是Set-Associative方式的两种特例。

在上世纪90年代,Direct Mapped机制大行其道,在Alpha 21064,21064A和21164处理器中,L1 I Cache和D Cache都使用了Direct Mapped方式和Write Through策略。直到Alpha 21264,在L1 Cache层面才开始使用2-Way Associative方式和Write Back策略[16][17][18]。即便如此Alpha 21264在L1 I Cache仍然做出了一些独特设计,采用了2-Way Set-Predict结构,在某种程度上看使用这种方式,L1 I Cache相当于工作在Direct Mapped方式中。

在90年代,世界上没有任何一个微架构能够与Alpha相提并论,没有任何一个公司有DEC在处理器微架构中的地位,来自DEC的结论几乎即为真理,而且这些结论都有非常深入的理论作为基础。与Fully-Associative和Set-Associative相比,Direct Mapped方式所需硬件资源非常有限,每一次存储器访问都固定到了一个指定的Cache Block。这种简单明了带来了一系列优点,最大的优点是在200~300MHz CPU主频的情况下,Load-Use Latency可以是1个Cycle。天下武功无坚不破,唯快不破。

至今很少有微架构在L1层面继续使用Direct Mapped方式,但是这种实现方式并没有如大家想象中糟糕。围绕着Direct Mapped方式,学术界做出了许多努力,其中带来最大影响的是Normal P. Jouppi书写的“Improving Direct-Mapped Cache Performance by Additionof a Small Fully-Associative Cache and PrefetchBuffers”,其中提到的Victim Cache,Stream Buffer[20]至今依然在活跃。

使DirectMapped方式逐步退出历史舞台的部分原因是CPU Core主频的增加使得Direct Mapped方式所带来的Load-Use Latency在相对缩小,更为重要的是呈平方级别增加的主存储器容量使得Cache容量相对在缩小。

从Cache MissRate的层面考虑,一个采用Direct Mapped方式容量为N的Cache其Miss Rate与采用2-Way Set-Associative方式容量为N/2的Cache几乎相同。这个Observation被John和David称为2:1 Cache Rule of Thumb[7]。这意味着采用Direct Mapped方式的Cache,所需要的Cache容量相对较大。

近些年L1Cache与主存储器容量间的比值不但没有缩小而是越来越大。L1 Cache的大小已经很少发生质的变化了,从Pentium的16/32KB L1 Cache到Sandy Bridge的64KB L1 Cache,Intel用了足足二十多年的时间。在这二十多年中,主存储器容量何止扩大了两千倍。相同的故事也发生在L2与L3 Cache中。这使得在采用Direct Mapped方式时,Cache的Miss Ratio逐步提高,也使得N-Way Set-Associative方式闪亮登场。

采用Set-Associative方式时,Cache被分解为S个Sets,其中每一个Set中有N个Ways。根据N的不同,Cache可以分为Fully-Associative, N-WaysSet-Associative或者是Direct Mapped。在Cache的总容量不变的情况下,即S×N的值为一个常数M时,N越大,则S越小,反之亦然。8-Way Set-Associative Cache的组成结构如图2‑4所示。

2.2 <wbr>Cache的组成结构

如图2‑4所示,在Cache Block中Real Address Tag字段与数据字段分离,因为这两类字段分别存在不同类型的存储器中。在同一个Set中,Real Address Tag阵列多使用CAM(Content Addressable Memory)存放,以利于并行查找PS(Parallel Search)方式的实现,在设计中也可以根据需要使用串行查找方式SS(Sequential Search)。与PS方式相比,SS方式使用的物理资源较少,但是当使用的Ways数较大时,采用这个方式的查找速度较慢。在现代微架构中,数据字段组成的阵列一般使用多端口,多Bank的SRAM。下文主要讨论PS的实现方式。

对于一个Cache,其总大小由存放Tag阵列和SRAM阵列组成,在参数N较低时也可以采用RAM Tag,本篇仅讨论CAM Tag,在功耗日益敏感的今天,Highly Associative Cache倾向于使用CAM Tag。在许多微架构中,如Nehalem微架构的L1 Cache为32KB[12],这是的大小是指SRAM阵列,没有包括Tag阵列。Tag阵列占用的Die Size不容忽略。

在说明Set-Associative方式和Tag阵列之前,我们进一步讨论NS这个参数。不同的处理器采用了不同的Cache映射方式,如Fully-Associative, N-WaysSet-Associative或者是Direct Mapped。如果使用NS参数进行描述,这三类方式本质上都是N-Ways Set-Associative方式,只是选用了不同的NS参数而已。

在使用N-WaysSet-Associative方式时,Cache首先被分解为多个Set。当S参数等于1时,即所有Cache Block使用一个Set进行管理时,这种方式即为Fully-Associative;N参数为1时的管理方式为Direct Mapped;当NS参数不为1时,使用的方式为N-Ways Set-Associative方式。在图2‑4中,N为8,这种方式被称为8-Way Set-Associative。

诸多研究结果表明,随着N的不断增大,Cache的Miss Ratio在逐步降低[7][23]。这并不意味着设计者可以使用更大的参数N。在很多情况下,使用更大的参数N并不会显著降低Miss Ratio,就单级Cache而言,8-Way Set-Associative与Fully-Associative方式从Miss Ratio层面上看效果相当[7]。许多微架构使用的16-Way或者更高的32-Way Set-Associative,并不是单纯为了降低Miss Ratio。

随着Way数的增加,即便Cache所使用的Data阵列保持不变,Cache使用的总资源以及Tag比较所需要的时间也在逐步增加。在一个实际的微架构中,貌似巨大无比的CPU Die放不下几片Cache,在实际设计中一个Die所提供的容量已经被利用的无以复加,很多貌似优秀的设计被不得已割舍。这也使得在诸多条件制约之下,参数N并不是越大越好。这个参数的选择是资源权衡的结果。

当S参数为1时,N等于M,此时Tag阵列的总Entry数目依然为M,但是对于CAM这样的存储器,单独的一个M大小的数据单元所耗费的Die资源,略微超过S个N大小的数据单元。随着N的提高,Tag阵列所消耗的比较时间将逐步增加,所需要的功耗也在逐级增大。在进一步讨论这些细节知识前,我们需要了解CAM的基本组成结构,如图2‑5所示。

2.2 <wbr>Cache的组成结构

图2‑5中所示的CAM中有3个Word,每一个Word由4个Bits组成,其中每一个Bit对应一个CAM Cell。其中每一个Word对应一条横向的ML(Match Line),由ML0~2组成。在一个CAM内,所有Word的所有Bits将同时进行查找。在一列中,Bits分别与两个SL(Serach Line)对应,包括SL0~3和~SL0~3#。其中一个Bit对应一个CAM Cell。

使用CAM进行查找时,需要首先将Search Word放入Search Data Register/Drivers中,之后这个Search Word分解为若干个Bits,通过SL或者~SL发送到所有CAM Cell中。其中每一个CAM Cell将Hit/Miss信息传递给各自的ML。所有ML信息将最后统一在一起,得出最后的Hit/Miss结论,同时也将给出在CAM的哪个地址命中的信息[1]。由此可以发现,由于CAM使用并行查找方式,其查找效率明显操作SRAM。

这也使得CAM得到了广泛应用。但是我们依然无法从这些描述中,获得随着CAM包含的Word数目增加,比较时间将逐步增加,所需要的功耗也在逐级增大这个结论,也因此无法解释Cache设计中为什么不能使用过多的Way。为此我们需要进一步去微观地了解CAM Cell的结构和Hit/Miss识别机制。在门级电路的实现中,一个CAM Cell的设计可以使用两种方式,一个是基于NOR,另一个是基于NAND,如图2‑6所示。

2.2 <wbr>Cache的组成结构

在上图中可以发现NOR-Type CAMCell和NAND-Type CACM Cell分别由4和3个MOSGET加上一个SRAM Cell组成,一个SRAM Cell通常由6个Transistor组成[2]。由此可以发现一个基本的NOR-Type CAM Cell由10个,NAND-Type CACM Cell由9个Transistor组成。

这不是NOR/NAND CAMCell的细节,NOR CAM Cell有9个Transistor的实现方式,NAND CAM Cell有10个Transistor的实现方式,这些由实现过程中的取舍决定。NOR和NAND CAM的主要区别是Word的查找策略,NOR CAM Cell采用并行查找方式,NAND CAM Cell使用级联方式进行查找,如图2‑7所示。

2.2 <wbr>Cache的组成结构

为节约篇幅,我省略如何对这些晶体管进行Precharge,Discharge,如何Evaluate,并最终确定一个Word是Hit还是Miss,读者可以进一步阅读[25]获得详细信息。较为重要的内容是从图2‑7中可以发现,当使用NAND CAM时,Word的匹配使用级联方式,MLn需要得到MLn-1的信息后才能继续进行,采用NOR CAM是全并行查找。仅从这些描述上似乎可以发现,NOR CAM在没有明显提高Transistor数目的前提之下,从本质上提高了匹配效率,貌似NAND CAM并没有太多优点。

事实并非如此。在使用NORCAM时,随着Word包含Bit数目的增加,ML上的负载数也随之增加。这些过多输入的与操作将带来延时和功耗。在图2‑7所示的N-Input与操作采用了One-Stage实现方式,需要使用Sense Amplifier降低延时,但是这个Sense Amplifier无论在工作或者处于Idle状态时的功耗都较大。当然在n较大时,Multi-Stage n-input AND Gate所产生的延时更不能接受。

即便使用了SenseAmplifier,也并不能解决全部问题。当时钟频率较高时,这种并联方式所产生的延时很难满足系统需求。使用NAND CAM方式是一推一关系,没有这种负载要求。在Cache的Tag中除了需要保存Real Address之外还有许多状态信息,这也加大了AND Gate的负担。

CAM除了横向判断一个Word是Hit还是Miss之外,还有另外一个重要问题,就是Search Data Register/Driver的驱动能力问题,这个问题进一步引申就是N-Way Set-Associative中N究竟多大才合理的问题。一个门能够驱动多少个负载和许多因素相关,频率,电流强度和连接介质等。对于一个运行在3.3GHz的L1 Cache而言,一个Cycle仅有300ps,在这么短的延时内,门级电路做不了太多事情。

我们可能有很多方法提高驱动能力,Buffering the fan-out,使用金属线介质或者更多级的驱动器,缩短走线距离等等。在所有追求极限的设计中,这些方法不是带来了过高的延时,就是提高了功耗。一个简单的方式是采用流水方式,使用更多的节拍,但是你可知我为了节省这一拍延时经历了多少努力。这一切使得在N-Ways Set-Associative方式中N的选择是一个痛苦的折中,也使得在现代微架构的L1 Cache中N不会太大。

尽管有这些困难,绝大多数现代微架构还是选择了N-Ways Set-Associative方式,只是对参数N进行了折中。在这种方式下,当CPU使用地址r(i)进行存储器访问时,首先使用函数f寻找合适的Set,即s(i) = f(r(i)),然后在将访问的地址的高字段与选中Set的Real Address Tag阵列进行联合比较,如果在Tag阵列中没有命中,表示Cache Miss;如果命中则进一步检查Cache Block状态信息,并将数据最终读出或者写入。

现代微架构多使用2-Ways,4-Ways,8-Ways或者16-Ways Set-Associative方式组成Cache的基本结构。Ways的数目多为2的幂,采用这种组成方式便于硬件实现。然而依然有例外存在,在有些处理器中可能出现10-Ways或者其他非2幂的Ways。

出现这种现象的主要原因是这个Way并非对等。在一个处理器系统中,微架构和外部设备,如显卡和各类PCIe设备,都可以进行存储器访问。这些存储器访问并不类同。在多数情况下,微架构经由LSQ,FLC,MLCs,之后通过LLC,最终与主存储器进行数据交换。外部设备进行DMA访问时,直接面对的是LLC和主存储器,并对L1 Cache和MLC产生简介影响。微架构与外部设备访问主存储器存在的差异,决定了在有些处理器中,LLC Way的构成并不一定是2的幂,而是由若干2的幂之和组成,如10-Ways Set-Associative可能是由一个8-Ways和一个2-Ways组成。

无论是软件还是硬件设计师都欣赏同构的规整,和由此带来的便利与精彩。但是在更多情况下,事物存在的差异性,使得严格的同构并不能发挥最大的功效,更多时候需要使用异构使同构最终成为可能。

在Cache中,不对等Way的产生除了因为访问路线并不一致之外,还有一个原因是为了降低Cache Miss Rate,有些微架构进行Way选择使用了不同的算法。如Skewed-Associative Cache[26]可以使用不用的Hash算法,f0和f1分别映射一个Set内的两个Way,采用这种方法在没有增加Set的Ways数目的情况下,有效降低了Cache Miss Rate。[26]的结论是在Cache总大小相同时,2-Way Skewed- Associative Cache的Hit Ratio与4-Way Associative Cache相当,其Hit Time与Direct Mapped方式接近。但是在Cache容量较大时,f0和f1的映射成本也随之加大,从而在一定程度上增加了Cache的访问时间。

在历史上还出现过其他的Cache组成结构,如Hash-rehash Cache,Column-Associative Cache等,本篇对此不再一一介绍。值得留意的是Parallel Multicolumn Cache[27],这种Cache的实现要点是综合了Direct Mapped Cache和N-Ways Set-Associative方式,在访问Cache时首先使用Direct Mapped策略以获得最短的检索时间,在DM方式没有命中后,再访问N-Ways方式组成的模块。

上述这些方式基本是围绕着DirectMapped进行优化,目前鲜有现代微架构继续使用这些方法,但是在一个广义Cache的设计中,如果仅存在一级Cache,这些方法依然有广泛活跃着。这也是本节在此提及这些算法的主要原因。

在体系结构领域,针对Cache的Way的处理上,还有很多算法,但是在结合整个Cache层次结构的复杂性之后,具有实用价值的算法并不多。在目前已实现的微架构中,使用的最多的方式依然是N-Ways Set-Associative。

在某些场景下,MissPenalty无法忍受,比如TLB Miss,无论是采用纯软件还是Hardware Assistance的方法,Miss Penalty的代价都过于昂贵。这使得架构师最终选择了Fully Associative实现方式。在现代微架构中,TLB的设计需要对Hit Time和Miss Rate的设计进行折中,TLB因此分为两级,L1和L2。L1-TLB的实现侧重于Hit Time参数,较小一些,多使用Fully Associative方式,对其的要求是Extremely Fast;L2 TLB的实现需要进一步考虑Miss Rate,通常较大一些,多使用N-Way Associative方式。



[1] 在Cache的设计中,地址信息并不是必要的。在Routing Table的查找中多使用了地址信息。

[2] SRAM Cell还可以使用8个Transistors的实现方式。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值