很多程序员认为Cache是透明的,处理器可以很聪明地安排他们书写的程序。他们非常幸运,可以安逸着忽略Cache,也安逸着被Cache忽略,日复一日,年复一年,机械地生产着各类代码。All of them are deceived。

    貌似并不存在的Cache,有意无意地制造了,正在制造,并必会制造着各类陷阱。也许在历经了各类苦难后,有些人能够发现Cache的少些特性,却愈发不可控制。掌握Cache的细节知识并不困难,只要能够真正做到静如止水。

Cache的工作原理

    处理器微架构访问Cache的方法与访问主存储器有类似之处。主存储器使用地址编码方式,微架构可以地址寻址方式访问这些存储器。Cache也使用了类似的地址编码方式,微架构也是使用这些地址操纵着各级Cache,可以将数据写入Cache,也可以从Cache中读出内容。只是这一切微架构针对Cache的操作并不是简单的地址访问操作。为简化起见,我们忽略各类Virtual Cache,讨论最基础的Cache访问操作,并借此讨论CPU如何使用TLB完成虚实地址转换,最终完成对Cache的读写操作。

     Cache的存在使得CPU Core的存储器读写操作略微显得复杂。CPU Core在进行存储器方式时,首先使用EPN(Effective Page Number)进行虚实地址转换,并同时使用CLN(Cache Line Number)查找合适的Cache Block。这两个步骤可以同时进行。在使用Virtual Cache时,还可以使用虚拟地址对Cache进行寻址。为简化起见,我们并不考虑Virtual Cache的实现细节。

    EPN经过转换后得到VPN,之后在TLB中查找并得到最终的RPN(Real Page Number)。如果期间发生了TLB Miss,将带来一系列的严重的系统惩罚,我们只讨论TLB Hit的情况,此时将很快获得合适的RPN,并依此得到PA(Physical Address)。

    在多数处理器微架构中,Cache由多行多列组成,使用CLN进行索引最终可以得到一个完整的Cache Block。但是在这个Cache Block中的数据并不一定是CPU Core所需要的。因此有必要进行一些检查,将Cache Block中存放的Address与通过虚实地址转换得到的PA进行地址比较(Compare Address)。如果结果相同而且状态位匹配,则表明Cache Hit。此时微架构再经过Byte Select and Align部件最终获得所需要的数据。如果发生Cache Miss,CPU需要使用PA进一步索引主存储器获得最终的数据。


    由上文的分析,我们可以发现,一个Cache Block由预先存放的地址信息,状态位和数据单元组成。一个Cache由多个这样的Cache Block组成,在不同的微架构中,可以使用不同的Cache Block组成结构。我们首先分析单个Cache Block的组成结构。单个Cache Block由Tag字段,状态位和数据单元组成,如图2‑2所示。

     其中Data字段存放该Cache Block中的数据,在多数处理器微架构中,其大小为32或者64字节。Status字段存放当前Cache Block的状态,在多数处理器系统中,这个状态字段包含MESI,MOESI或者MESIF这些状态信息,在有些微架构的Cache Block中,还存在一个L位,表示当前Cache Block是否可以锁定。许多将Cache模拟成SRAM的微架构就是利用了这个L位。有关MOESIFL这些状态位的说明将在下文中详细描述。在多核处理器和复杂的Cache Hierarchy环境下,状态信息远不止MOESIF。

    RAT(Real Address Tag)记录在该Cache Block中存放的Data字段与那个地址相关,在RAT中存放的是部分物理地址信息,虽然在一个CPU中物理地址可能有40,46或者48位,但是在Cache中并不需要存放全部地址信息。因为从Cache的角度上看,CPU使用的地址被分解成为了若干段,如图2‑3所示。

    这个地址也可以理解为CPU访问Cache使用的地址,由多个数据段组成。首先需要说明的是Cache Line Index字段。这一字段与图2‑1中的Cache Line Number类似,CPU使用该字段从Cache中选择一个或者一组Entry[2]。

    Bank和Byte字段之和确定了单个Cache的Data字段长度,通常也将这个长度称为Cache 行长度,图2‑3所示的微架构中的Cache Block长度为64字节。目前多数支持DDR3 SDRAM的微架构使用的Cache Block长度都是64字节。部分原因是由于DDR3 SDRAM的一次Burst Line为8[24],一次基本Burst操作访问的数据大小为64字节。

    在处理器微架构中,将地址为Bank和Byte两个字段出于提高Cache Block访问效率的考虑。Multi-Bank Mechanism是一种常用的提高访问效率的方法,采用这种机制后,CPU访问Cache时,只要不是对同一个Bank进行访问,即可并发执行。Byte字段决定了Cache的端口位宽,在现代微架构中,访问Cache的总线位宽为64位或者为128位。

    剩余的字段即为Real Address Tag,这个字段与单个Cache中的Real Address Tag的字段长度相同。CPU使用地址中的Real Address Tag字段与Cache Block的对应字段和一些状态位进行联合比较,判断其访问数据是否在Cache中命中。

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

    写作时回忆Sector Buffer机制时写下了这些文字。在现代处理器中,Cache Block的组成方式大多都采用了Set-Associative方式。与Set-Associative方式相关的Cache Block组成方式还有Direct Mapped和Fully-Associative两种机制。Direct MappedFully-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策略。即便如此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 Addition of a Small Fully-Associative Cache and Prefetch Buffers”,其中提到的Victim Cache,Stream Buffer[20]至今依然在活跃。

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

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

    近些年L1 Cache与主存储器容量间的比值不但没有缩小而是越来越大。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-Ways Set-Associative或者是Direct Mapped。在Cache的总容量不变的情况下,即S×N的值为一个常数M时,N越大,则S越小,反之亦然。8-Way Set-Associative Cache的组成结构如图2‑4所示。

    如图2‑4所示,在Cache Block中Real AddressTag字段与数据字段分离,因为这两类字段分别存在不同类型的存储器中。在同一个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 ,这是的大小是指SRAM阵列,没有包括Tag阵列。Tag阵列占用的Die Size不容忽略。

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

    在使用N-Ways Set-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在逐步降低。这并不意味着设计者可以使用更大的参数N。在很多情况下,使用更大的参数N并不会显著降低Miss Ratio,就单级Cache而言,8-Way Set-Associative与Fully-Associative方式从Miss Ratio层面上看效果相当。许多微架构使用的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‑5中所示的CAM中有3个Word,每一个Word由4个Bits组成,其中每一个Bit对应一个CAM Cell。其中每一个Word对应一条横向的ML(Match Line),由ML0~2组成。在一个CAM内,所有Word的所有Bits将同时进行查找。在一列中,Bits分别与两个SL(Serach Line)对应,包括SL03和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所示。

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

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

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

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

    即便使用了Sense Amplifier,也并不能解决全部问题。当时钟频率较高时,这种并联方式所产生的延时很难满足系统需求。使用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方式组成的模块。

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

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

    在某些场景下,Miss Penalty无法忍受,比如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的实现方式

NAND型的比NOR型的省电,原因在于NOR型是不命中时漏电流大,cache至多命中一行,其他行都不命中,所以此时功耗太大。NAND刚好相反。

转载自:http://blog.sina.com.cn/s/blog_6472c4cc0102duzq.html
作者 :sailing

Cache组成及工作原理相关推荐

  1. cache相关概念及工作原理介绍

    cache相关概念及工作原理介绍 笔者这篇文章主要从使用者的角度介绍cache的相关概念和工作原理. 一. cache是什么,为什么要用它 关于cache是什么,为什么要用它.我们从这个表格说起.下图 ...

  2. 【王道计组笔记】Cache高速缓存基本工作原理

    缓存器 的引入: [王道计组笔记]高速缓存器:局部性原理及性能分析_muse_age的博客-CSDN博客 1.主存的块放到Cache中哪个位置?CPU向缓存中读取一个数据过程? (1)空位随意放:全相 ...

  3. Cache —— 局部性原理和工作原理

    一.程序访问的局部性原理 程序访问的局部性原理包括时间局部性和空间局部性. 空间局部性:在最近的未来要用到的信息(指令和数据),很可能与现在正在使用的信息在存储空间上是邻近的 时间局部性:在最近的未来 ...

  4. 深入理解 Cache 工作原理

    欢迎关注方志朋的博客,回复"666"获面试宝典 大家好,今天给大家分享一篇关于 Cache 的硬核的技术文,基本上关于Cache的所有知识点都可以在这篇文章里看到. 关于 Cach ...

  5. Cache 工作原理,Cache 一致性,你想知道的都在这里

    欢迎关注方志朋的博客,回复"666"获面试宝典 可以随便到网上查一查,各大互联网公司笔试面试特别喜欢考一道算法题,即 LRU缓存机制,又顺手查了一下LRU缓存机制最近有哪些企业喜欢 ...

  6. Cache 工作原理、Cache 一致性,你想知道的都在这里

    作者 | 桔里猫 来源 | https://zhuanlan.zhihu.com/p/386919471 可以随便到网上查一查,各大互联网公司笔试面试特别喜欢考一道算法题,即 LRU缓存机制,又顺手查 ...

  7. 深入理解Cache工作原理

    大家好,今天给大家分享一篇关于 Cache 的硬核的技术文,基本上关于Cache的所有知识点都可以在这篇文章里看到. 关于 Cache 这方面内容图比较多,不想自己画了,所以图都来自<Compu ...

  8. 计组之存储系统:5、cache(cache功能、cache工作原理、cache性能分析)

    5.cache 思维导图 为什么要cache? Cache的工作原理 局部性原理 性能分析(加入cache) 空间局部性中的"附近"怎么定义? 待解决的问题? 思维导图 为什么要c ...

  9. Cache工作原理,Cache一致性,你想知道的都在这里

    可以随便到网上查一查,各大互联网公司笔试面试特别喜欢考一道算法题,即 LRU缓存机制,又顺手查了一下LRU缓存机制最近有哪些企业喜欢考察,超级大热门! 今天给大家分享一篇关于 Cache 的硬核的技术 ...

最新文章

  1. python 学术_Python
  2. sublime Text 2 配置以及 Python环境搭建
  3. [原创]K8域控植入脚本生成器(内网渗透/RPC不可用解决方案)
  4. B站王道论坛计算机网络,成都理工大学计算机网络考研学长经验分享
  5. python分布式日志收集系统_Go实现海量日志收集系统(一)
  6. Fabric--区块链应用开发
  7. Java中获取近七天的日期(包含今天)
  8. 计算机关机后自行启动,电脑关机后自动开机
  9. QtCreator5.12.6安装图文教程
  10. Navicat连接出现了2003-Can’t connect to MySQL server on ‘localhost’…(已解决)
  11. STM32——整形变量转换为字符变量并通过串口发送出去
  12. Android contacts 的详解
  13. centos7下载,centos iso文件下载
  14. [C++]_ELVE_Windows下QT5.12连接MySql8.0解决方案
  15. varnish 高性能加速器
  16. 沐风水库理论:企业微信生态营销秘密核武器
  17. git分支开发练习以及创建文件提交到版本库
  18. 装机软件测试工资,实际性能测试及总结_DIY攒机装机不求人-中关村在线
  19. Unity URP渲染管线下体积光的实现
  20. Java深度学习系列——对象流和序列化

热门文章

  1. 各种反弹shell方式
  2. soh计算机网络,计算机网络知识点
  3. 复试面试题——数据库
  4. 如何理解三大微分中值定理?
  5. 美团 PK 抖音,内容与商业化之间的较量谁能赢?
  6. 及刻周边惠:拥抱HarmonyOS原子化服务
  7. 微信文章右上角 不显示推送到亚马逊kindle服务号
  8. 扫码自助饮料机真的能够完善市场吗?点赋科技预测
  9. ubuntu下的usb 转串口的使用
  10. 全国民用航空机场分布数据[2019]