精华内容
下载资源
问答
  • 采用一级cache设计对五级流水线CPU进行优化,Cache的工作原理是基于程序访问的局部性。根据程序的局部性原理,可以在主存和CPU通用寄存器之间设置一个高速的容量相对较小的存储器,把正在执行的指令地址附近的一部分...
  • 一般来说我们买CPU时都会重视L2的大小,而没有几个在L1上做文章L1 Cache(一级缓存)是CPU第一层高速缓存,分为数据缓存和指令缓存。内置的L1高速缓存的容量和结构对CPU的性能影响较大,不过高速缓冲存储器均由静态RAM...
    
    

    缓存是介于应用程序和物理数据源之间,其作用是为了降低应用程序对物理数据源访问的频次,从而提高了应用的运行性能。缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事件会同步缓存和物理数据源的数据。

      缓存的介质一般是内存,所以读写速度很快。但如果缓存中存放的数据量非常大时,也会用硬盘作为缓存介质。缓存的实现不仅仅要考虑存储的介质,还要考虑到管理缓存的并发访问和缓存数据的生命周期。

    
    
    总体来说,现在CPU的L1缓存的大小差别不大,主要差的就是L2,而L2的增加会使性能大幅度的提升,但是相对来说成本增加的更大。一般来说我们买CPU时都会重视L2的大小,而没有几个在L1上做文章

    L1 Cache(一级缓存)是CPU第一层高速缓存,分为数据缓存和指令缓存。内置的L1高速缓存的容量和结构对CPU的性能影响较大,不过高速缓冲存储器均由静态RAM组成,结构较复杂,在CPU管芯面积不能太大的情况下,L1级高速缓存的容量不可能做得太大。一般服务器CPU的L1缓存的容量通常在32—4096KB。

    L2 CACHE=二级缓存
    它是处理器内部的一些缓冲存储器,其作用跟内存一样。 它是怎么出现的呢? 要上溯到上个世纪80年代,由于处理器的运行速度越来越快,慢慢地,处理器需要从内存中读取数据的速度需求就越来越高了。然而内存的速度提升速度却很缓慢,而能高速读写数据的内存价格又非常高昂,不能大量采用。从性能价格比的角度出发,英特尔等处理器设计生产公司想到一个办法,就是用少量的高速内存和大量的低速内存结合使用,共同为处理器提供数据。这样就兼顾了性能和使用成本的最优。而那些高速的内存因为是处于CPU和内存之间的位置,又是临时存放数据的地方,所以就叫做缓冲存储器了,简称“缓存”。它的作用就像仓库中临时堆放货物的地方一样,货物从运输车辆上放下时临时堆放在缓存区中,然后再搬到内部存储区中长时间存放。货物在这段区域中存放的时间很短,就是一个临时货场。 最初缓存只有一级,后来处理器速度又提升了,一级缓存不够用了,于是就添加了二级缓存。二级缓存是比一级缓存速度更慢,容量更大的内存,主要就是做一级缓存和内存之间数据临时交换的地方用。现在,为了适应速度更快的处理器P4EE,已经出现了三级缓存了,它的容量更大,速度相对二级缓存也要慢一些,但是比内存可快多了。 缓存的出现使得CPU处理器的运行效率得到了大幅度的提升,这个区域中存放的都是CPU频繁要使用的数据,所以缓存越大处理器效率就越高,同时由于缓存的物理结构比内存复杂很多,所以其成本也很高。
    大量使用二级缓存带来的结果是处理器运行效率的提升和成本价格的大幅度不等比提升。举个例子,服务器上用的至强处理器和普通的P4处理器其内核基本上是一样的,就是二级缓存不同。至强的二级缓存是2MB~16MB,P4的二级缓存是512KB,于是最便宜的至强也比最贵的P4贵,原因就在二级缓存不同。
    展开全文
  • mybatis一级缓存(session cache)引发的问题

    问题回顾

    最近项目功能单元测试中,出现了一个奇怪的bug。远程调试发现,程序进行了2次相同的查询,返回了实体类(ClassA)的2个对象:classAInstance1和classAInstance2,当修改classAInstance1.property1时,竟然classAInstance2.property1也被改了!!! 很快发现classAInstance1和classAInstance2地址是相同的,它们是同一个内存对象!

    原因分析

    经调试发现,mybatis返回的实体类的内存地址是相同的!于是猜测是mybatis缓存的原因,于是进行了下面的测试验证

    测试验证

    经过单元测试验证,不开启事务的情况下,多次相同的查询,返回对象地址不相等, 代码略。
    经过单元测试验证,在一个事务内,多次相同的查询,返回对象地址相等, 代码如下:

    
        @Resource
        private MybatisSessionCacheTestService mybatisSessionCacheTestService;
    
        @Test
        public void test_mybatis_sql_session_cache(){
            Long id = 100L;
            ClassA classAInstance1 = mybatisSessionCacheTestService.queryById(id);
            ClassA classAInstance2 = mybatisSessionCacheTestService.queryById(id);
            //assert mybatis cache is on
            Assert.assertTrue(classAInstance1 == classAInstance2);
        }
        @Service
        public class MybatisSessionCacheTestService {
            @Resource
            private ClassADAO classDAO;
    
            @Transactional //spring 事务注解
            public ClassA queryById(Long id){
                return classADAO.queryById(id);
            }
        }

    解决方案

    • 1.把查询提前到事务之前(之外),这样只解决了个别问题,解决并不彻底。
    • 2.在mybatis的mapper xml里配置每次清空缓存flushCache:
    <select id="selectById" resultType="ClassA" flushCache="true">
    ...
    </select>

    附录:mybatis缓存介绍

    一级缓存

    即session缓存,作用域为 Session,当 Session flush 或 close 之后,该Session中的所有 Cache 就将清空,默认开启。

    注意 集成spring(使用mybatis-spring)时:

    • 每次查询spring会重新创建SqlSession,所以一级缓存是不生效的。
    • 而当开启事务时,spring会使用同一个SqlSession做查询,所以这个情况下一级缓存是生效的

    二级缓存

    即全局缓存,其作用域为 Mapper(Namespace),默认关闭。

    其他参考:

    附注jar包版本:

    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.3.0</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>1.3.0</version>
    </dependency>
    展开全文
  • L1 Cache(一级缓存)

    万次阅读 2015-05-10 11:48:11
    CPU缓存(Cache Memory)是位于CPU与内存之间的临时存储器,它的容量比内存小的多但是交换速度却比内存要快得多。缓存的出现主要是为了解决CPU运算速度与内存读写速度不匹配的矛盾,因为CPU运算速度要比内存读写速度...

    CPU缓存(Cache Memory)是位于CPU与内存之间的临时存储器,它的容量比内存小的多但是交换速度却比内存要快得多。缓存的出现主要是为了解决CPU运算速度与内存读写速度不匹配的矛盾,因为CPU运算速度要比内存读写速度快很多,这样会使CPU花费很长时间等待数据到来或把数据写入内存。在缓存中的数据是内存中的一小部分,但这一小部分是短时间内CPU即将访问的,当CPU调用大量数据时,就可避开内存直接从缓存中调用,从而加快读取速度。

    简介  缓存大小也是CPU的重要指标之一,而且缓存的结构和大小对CPU速度的影响非常大,CPU内缓存的运行频率极高,一般是和处理器同频运作,工作效率远远大于系统内存和硬盘。实际工作时,CPU往往需要重复读取同样的数据块,而缓存容量的增大,可以大幅度提升CPU内部读取数据的命中率,而不用再到内存或者硬盘上寻找,以此提高系统性能。但是从CPU芯片面积和成本的因素来考虑,缓存都很小。

    概念

    L1 Cache(一级缓存)

      L1

      

    CPU缓存

    Cache(一级缓存)是CPU第一层高速缓存,分为数据缓存和指令缓存。内置的L1高速缓存的容量和结构对CPU的性能影响较大,不过高速缓冲存储器均由静态RAM组成,结构较复杂,在CPU管芯面积不能太大的情况下,L1级高速缓存的容量不可能做得太大。一般服务器CPU的L1缓存的容量通常在32—256KB。

    L2 Cache(二级缓存)

      L2 Cache(二级缓存)是CPU的第二层高速缓存,分内部和外部两种芯片。内部的芯片二级缓存运行速度与主频相同,而外部的二级缓存则只有主频的一半。L2高速缓存容量也会影响CPU的性能,原则是越大越好,现在家庭用CPU容量最大的是4MB,而服务器和工作站上用CPU的L2高速缓存更高达2MB—4MB,有的高达8MB或者19MB。

    L3 Cache(三级缓存)

      L3 C

      

    CPU缓存

    ache(三级缓存),分为两种,早期的是外置,现在的都是内置的。而它的实际作用即是,L3缓存的应用可以进一步降低内存延迟,同时提升大数据量计算时处理器的性能。降低内存延迟和提升大数据量计算能力对游戏都很有帮助。而在服务器领域增加L3缓存在性能方面仍然有显著的提升。比方具有较大L3缓存的配置利用物理内存会更有效,故它比较慢的磁盘I/O子系统可以处理更多的数据请求。具有较大L3缓存的处理器提供更有效的文件系统缓存行为及较短消息和处理器队列长度。

      其实最早的L3缓存被应用在AMD发布的K6-III处理器上,当时的L3缓存受限于制造工艺,并没有被集成进芯片内部,而是集成在主板上。在只能够和系统总线频率同步的L3缓存同主内存其实差不了多少。后来使用L3缓存的是英特尔为服务器市场所推出的Itanium处理器。接着就是P4EE和至强MP。Intel还打算推出一款9MB L3缓存的Itanium2处理器,和以后24MB L3缓存的双核心Itanium2处理器。

      但基本上L3缓存对处理器的性能提高显得不是很重要,比方配备1MB L3缓存的Xeon MP处理器却仍然不是Opteron的对手,由此可见前端总线的增加,要比缓存增加带来更有效的性能提升。

    作用

      高

      

    CPU缓存

    速缓冲存储器Cache是位于CPU与内存之间的临时存储器,它的容量比内存小但交换速度快。

      在Cache中的数据是内存中的一小部分,但这一小部分是短时间内CPU即将访问的,当CPU调用大量数据时,就可避开内存直接从Cache中调用,从而加快读取速度。由此可见,在CPU中加入Cache是一种高效的解决方案,这样整个内存储器(Cache+内存)就变成了既有Cache的高速度,又有内存的大容量的存储系统了。

      Cache对CPU的性能影响很大,主要是因为CPU的数据交换顺序和CPU与Cache间的带宽引起的。

    高速缓存的工作原理

    1、读取顺序

      CPU要

      

    CPU缓存

    读取一个数据时,首先从Cache中查找,如果找到就立即读取并送给CPU处理;如果没有找到,就用相对慢的速度从内存中读取并送给CPU处理,同时把这个数据所在的数据块调入Cache中,可以使得以后对整块数据的读取都从Cache中进行,不必再调用内存。

      正是这样的读取机制使CPU读取Cache的命中率非常高(大多数CPU可达90%左右),也就是说CPU下一次要读取的数据90%都在Cache中,只有大约10%需要从内存读取。这大大节省了CPU直接读取内存的时间,也使CPU读取数据时基本无需等待。总的来说,CPU读取数据的顺序是先Cache后内存。

    2、缓存分类

      前面是把Cache作为一个整体来考虑的,现在要分类分析了。Intel从Pentium开始将Cache分开,通常分为一级高速缓存L1和二级高速缓存L2。在以往的观念中,L1 Cache是集成在CPU中的,被称为片内Cache。在L1中还分数据Cache(D-Cache)和指令Cache(I-Cache)。它们分别用来存放数据和执行这些数据的指令,而且两个Cache可以同时被CPU访问,减少了争用Cache所造成的冲突,提高了处理器效能。

      在P4处理器中使用了一种先进的一级指令Cache——动态跟踪缓存。它直接和执行单元及动态跟踪引擎相连,通过动态跟踪引擎可以很快地找到所执行的指令,并且将指令的顺序存储在追踪缓存里,这样就减少了主执行循环的解码周期,提高了处理器的运算效率。

      以前的L2 Cache没集成在CPU中,而在主板上或与CPU集成在同一块电路板上,因此也被称为片外Cache。但从PⅢ开始,由于工艺的提高L2 Cache被集成在CPU内核中,以相同于主频的速度工作,结束了L2 Cache与CPU大差距分频的历史,使L2 Cache与L1 Cache在性能上平等,得到更高的传输速度。L2Cache只存储数据,因此不分数据Cache和指令Cache。在CPU核心不变化的情况下,增加L2 Cache的容量能使性能提升,同一核心的CPU高低端之分往往也是在L2 Cache上做手脚,可见L2 Cache的重要性。现在CPU的L1 Cache与L2 Cache惟一区别在于读取顺序。

    3、读取命中率

      CPU在Cache中找到有用的数据被称为命中,当Cache中没有CPU所需的数据时(这时称为未命中),CPU才访问内存。从理论上讲,在一颗拥有2级Cache的CPU中,读取L1 Cache的命中率为80%。也就是说CPU从L1 Cache中找到的有用数据占数据总量的80%,剩下的20%从L2 Cache读取。由于不能准确预测将要执行的数据,读取L2的命中率也在80%左右(从L2读到有用的数据占总数据的16%)。那么还有的数据就不得不从内存调用,但这已经是一个相当小的比例了。在一些高端领域的CPU(像Intel的Itanium)中,我们常听到L3 Cache,它是为读取L2 Cache后未命中的数据设计的—种Cache,在拥有L3 Cache的CPU中,只有约5%的数据需要从内存中调用,这进一步提高了CPU的效率。

      为了保证CPU访问时有较高的命中率,Cache中的内容应该按一定的算法替换。一种较常用的算法是“最近最少使用算法”(LRU算法),它是将最近一段时间内最少被访问过的行淘汰出局。因此需要为每行设置一个计数器,LRU算法是把命中行的计数器清零,其他各行计数器加1。当需要替换时淘汰行计数器计数值最大的数据行出局。这是一种高效、科学的算法,其计数器清零过程可以把一些频繁调用后再不需要的数据淘汰出Cache,提高Cache的利用率。 缓存技术的发展

      总之,在传输速度有较大差异的设备间都可以利用Cache作为匹配来调节差距,或者说是这些设备的传输通道。在显示系统、硬盘和光驱,以及网络通讯中,都需要使用Cache技术。但Cache均由静态RAM组成,结构复杂,成本不菲,使用现有工艺在有限的面积内不可能做得很大,不过,这也正是技术前进的源动力,有需要才有进步!

    CPU缓存

    基本简介

      CPU缓存(Cache Memory)是位于CPU与内存之间的临时存储器,它的容量比内存小的多但是交换速度却比内存要快得多。缓存的出现主要是为了解决CPU运算速度与内存读写速度不匹配的矛盾,因为CPU运算速度要比内存读写速度快很多,这样会使CPU花费很长时间等待数据到来或把数据写入内存。在缓存中的数据是内存中的一小部分,但这一小部分是短时间内CPU即将访问的,当CPU调用大量数据时,就可避开内存直接从缓存中调用,从而加快读取速度。由此可见,在CPU中加入缓存是一种高效的解决方案,这样整个内存储器(缓存 内存)就变成了既有缓存的高速度,又有内存的大容量的存储系统了。缓存对CPU的性能影响很大,主要是因为CPU的数据交换顺序和CPU与缓存间的带宽引起的。

    缓存的工作原理

      缓存的工作原理是当CPU要读取一个数据时,首先从缓存中查找,如果找到就立即读取并送给CPU处理;如果没有找到,就用相对慢的速度从内存中读取并送给CPU处理,同时把这个数据所在的数据块调入缓存中,可以使得以后对整块数据的读取都从缓存中进行,不必再调用内存。

      正是这样的读取机制使CPU读取缓存的命中率非常高(大多数CPU可达90%左右),也就是说CPU下一次要读取的数据90%都在缓存中,只有大约10%需要从内存读取。这大大节省了CPU直接读取内存的时间,也使CPU读取数据时基本无需等待。总的来说,CPU读取数据的顺序是先缓存后内存。

    缓存是采用SRAM存储器

      目前缓存基本上都是采用SRAM存储器,SRAM是英文Static RAM的缩写,它是一种具有静态存取功能的存储器,不需要刷新电路即能保存它内部存储的数据。不像DRAM内存那样需要刷新电路,每隔一段时间,固定要对DRAM刷新充电一次,否则内部的数据即会消失,因此SRAM具有较高的性能,但是SRAM也有它的缺点,即它的集成度较低,相同容量的DRAM内存可以设计为较小的体积,但是SRAM却需要很大的体积,这也是目前不能将缓存容量做得太大的重要原因。它的特点归纳如下:优点是节能、速度快、不必配合内存刷新电路、可提高整体的工作效率,缺点是集成度低、相同的容量体积较大、而且价格较高,只能少量用于关键性系统以提高效率。

    CPU缓存的分为级

    基本简介

      按照数据读取顺序和与CPU结合的紧密程度,CPU缓存可以分为一级缓存,二级缓存,部分高端CPU还具有三级缓存,每一级缓存中所储存的全部数据都是下一级缓存的一部分,这三种缓存的技术难度和制造成本是相对递减的,所以其容量也是相对递增的。当CPU要读取一个数据时,首先从一级缓存中查找,如果没有找到再从二级缓存中查找,如果还是没有就从三级缓存或内存中查找。一般来说,每级缓存的命中率大概都在80%左右,也就是说全部数据量的80%都可以在一级缓存中找到,只剩下20%的总数据量才需要从二级缓存、三级缓存或内存中读取,由此可见一级缓存是整个CPU缓存架构中最为重要的部分。

    一级缓存

      一级缓存(Level 1 Cache)简称L1 Cache,位于CPU内核的旁边,是与CPU结合最为紧密的CPU缓存,也是历史上最早出现的CPU缓存。由于一级缓存的技术难度和制造成本最高,提高容量所带来的技术难度增加和成本增加非常大,所带来的性能提升却不明显,性价比很低,而且现有的一级缓存的命中率已经很高,所以一级缓存是所有缓存中容量最小的,比二级缓存要小得多。

      一般来说,一级缓存可以分为一级数据缓存(Data Cache,D-Cache)和一级指令缓存(Instruction Cache,I-Cache)。

      二者分别用来存放数据以及对执行这些数据的指令进行即时解码,而且两者可以同时被CPU访问,减少了争用Cache所造成的冲突,提高了处理器效能。目前大多数CPU的一级数据缓存和一级指令缓存具有相同的容量,例如AMD的Athlon XP就具有64KB的一级数据缓存和64KB的一级指令缓存,其一级缓存就以64KB 64KB来表示,其余的CPU的一级缓存表示方法以此类推。

      Intel的采用NetBurst架构的CPU(最典型的就是Pentium 4)的一级缓存有点特殊,使用了新增加的一种一级追踪缓存(Execution Trace Cache,T-Cache或ETC)来替代一级指令缓存,容量为12KμOps,表示能存储12K条即12000条解码后的微指令。一级追踪缓存与一级指令缓存的运行机制是不相同的,一级指令缓存只是对指令作即时的解码而并不会储存这些指令,而一级追踪缓存同样会将一些指令作解码,这些指令称为微指令(micro-ops),而这些微指令能储存在一级追踪缓存之内,无需每一次都作出解码的程序,因此一级追踪缓存能有效地增加在高工作频率下对指令的解码能力,而μOps就是micro-ops,也就是微型操作的意思。它以很高的速度将μops提供给处理器核心。Intel NetBurst微型架构使用执行跟踪缓存,将解码器从执行循环中分离出来。这个跟踪缓存以很高的带宽将uops提供给核心,从本质上适于充分利用软件中的指令级并行机制。Intel并没有公布一级追踪缓存的实际容量,只知道一级追踪缓存能储存12000条微指令(micro-ops)。所以,我们不能简单地用微指令的数目来比较指令缓存的大小。实际上,单核心的NetBurst架构CPU使用8Kμops的缓存已经基本上够用了,多出的4kμops可以大大提高缓存命中率。而如果要使用超线程技术的话,12KμOps就会有些不够用,这就是为什么有时候Intel处理器在使用超线程技术时会导致性能下降的重要原因。

      例如Northwood核心的一级缓存为8KB 12KμOps,就表示其一级数据缓存为8KB,一级追踪缓存为12KμOps;而Prescott核心的一级缓存为16KB 12KμOps,就表示其一级数据缓存为16KB,一级追踪缓存为12KμOps。在这里12KμOps绝对不等于12KB,单位都不同,一个是μOps,一个是Byte(字节),而且二者的运行机制完全不同。所以那些把Intel的CPU一级缓存简单相加,例如把Northwood核心说成是20KB一级缓存,把Prescott核心说成是28KB一级缓存,并且据此认为Intel处理器的一级缓存容量远远低于AMD处理器128KB的一级缓存容量的看法是完全错误的,二者不具有可比性。在架构有一定区别的CPU对比中,很多缓存已经难以找到对应的东西,即使类似名称的缓存在设计思路和功能定义上也有区别了,此时不能用简单的算术加法来进行对比;而在架构极为近似的CPU对比中,分别对比各种功能缓存大小才有一定的意义。

    二级缓存

      CPU缓存(Cache Memory)是位于CPU与内存之间的临时存储器,它的容量比内存小但交换速度快。在缓存中的数据是内存中的一小部分,但这一小部分是短时间内CPU即将访问的,当CPU调用大量数据时,就可避开内存直接从缓存中调用,从而加快读取速度。由此可见,在CPU中加入缓存是一种高效的解决方案,这样整个内存储器(缓存 内存)就变成了既有缓存的高速度,又有内存的大容量的存储系统了。缓存对CPU的性能影响很大,主要是因为CPU的数据交换顺序和CPU与缓存间的带宽引起的。

    cpu及CPU缓存图片锦集(15张)

    CPU缓存读取数据的顺序

      缓存的工作原理是当CPU要读取一个数据时,首先从缓存中查找,如果找到就立即读取并送给CPU处理;如果没有找到,就用相对慢的速度从内存中读取并送给CPU处理,同时把这个数据所在的数据块调入缓存中,可以使得以后对整块数据的读取都从缓存中进行,不必再调用内存。

      正是这样的读取机制使CPU读取缓存的命中率非常高(大多数CPU可达90%左右),也就是说CPU下一次要读取的数据90%都在缓存中,只有大约10%需要从内存读取。这大大节省了CPU直接读取内存的时间,也使CPU读取数据时基本无需等待。总的来说,CPU读取数据的顺序是先缓存后内存。

      最早先的CPU缓存是个整体的,而且容量很低,英特尔公司从Pentium时代开始把缓存进行了分类。当时集成在CPU内核中的缓存已不足以满足CPU的需求,而制造工艺上的限制又不能大幅度提高缓存的容量。因此出现了集成在与CPU同一块电路板上或主板上的缓存,此时就把 CPU内核集成的缓存称为一级缓存,而外部的称为二级缓存。一级缓存中还分数据缓存(Data Cache,D-Cache)和指令缓存(Instruction Cache,I-Cache)。二者分别用来存放数据和执行这些数据的指令,而且两者可以同时被CPU访问,减少了争用Cache所造成的冲突,提高了处理器效能。英特尔公司在推出Pentium 4处理器时,用新增的一种一级追踪缓存替代指令缓存,容量为12KμOps,表示能存储12K条微指令。

    CPU缓存的速度与效率

      随着CPU制造工艺的发展,二级缓存也能轻易的集成在CPU内核中,容量也在逐年提升。现在再用集成在CPU内部与否来定义一、二级缓存,已不确切。而且随着二级缓存被集成入CPU内核中,以往二级缓存与CPU大差距分频的情况也被改变,此时其以相同于主频的速度工作,可以为CPU提供更高的传输速度。

      二级缓存是CPU性能表现的关键之一,在CPU核心不变化的情况下,增加二级缓存容量能使性能大幅度提高。而同一核心的CPU高低端之分往往也是在二级缓存上有差异,由此可见二级缓存对于CPU的重要性。

      CPU在缓存中找到有用的数据被称为命中,当缓存中没有CPU所需的数据时(这时称为未命中),CPU才访问内存。从理论上讲,在一颗拥有二级缓存的CPU中,读取一级缓存的命中率为80%。也就是说CPU一级缓存中找到的有用数据占数据总量的80%,剩下的20%从二级缓存中读取。由于不能准确预测将要执行的数据,读取二级缓存的命中率也在80%左右(从二级缓存读到有用的数据占总数据的16%)。那么还有的数据就不得不从内存调用,但这已经是一个相当小的比例了。目前的较高端的CPU中,还会带有三级缓存,它是为读取二级缓存后未命中的数据设计的—种缓存,在拥有三级缓存的CPU中,只有约5%的数据需要从内存中调用,这进一步提高了CPU的效率。

      为了保证CPU访问时有较高的命中率,缓存中的内容应该按一定的算法替换。一种较常用的算法是“最近最少使用算法”(LRU算法),它是将最近一段时间内最少被访问过的行淘汰出局。因此需要为每行设置一个计数器,LRU算法是把命中行的计数器清零,其他各行计数器加1。当需要替换时淘汰行计数器计数值最大的数据行出局。这是一种高效、科学的算法,其计数器清零过程可以把一些频繁调用后再不需要的数据淘汰出缓存,提高缓存的利用率。

      CPU产品中,一级缓存的容量基本在4KB到64KB之间,二级缓存的容量则分为128KB、256KB、512KB、1MB、2MB等。一级缓存容量各产品之间相差不大,而二级缓存容量则是提高CPU性能的关键。二级缓存容量的提升是由CPU制造工艺所决定的,容量增大必然导致CPU内部晶体管数的增加,要在有限的CPU面积上集成更大的缓存,对制造工艺的要求也就越高。

      双核心CPU的二级缓存比较特殊,和以前的单核心CPU相比,最重要的就是两个内核的缓存所保存的数据要保持一致,否则就会出现错误,为了解决这个问题不同的CPU使用了不同的办法:

    Intel双核心处理器的二级缓存

      目前Intel的双核心CPU主要有Pentium D、Pentium EE、Core Duo三种,其中Pentium D、Pentium EE的二级缓存方式完全相同。Pentium D和Pentium EE的二级缓存都是CPU内部两个内核具有互相独立的二级缓存,其中,8xx系列的Smithfield核心CPU为每核心1MB,而9xx系列的Presler核心CPU为每核心2MB。这种CPU内部的两个内核之间的缓存数据同步是依靠位于主板北桥芯片上的仲裁单元通过前端总线在两个核心之间传输来实现的,所以其数据延迟问题比较严重,性能并不尽如人意。

      Core Duo使用的核心为Yonah,它的二级缓存则是两个核心共享2MB的二级缓存,共享式的二级缓存配合Intel的“Smart cache”共享缓存技术,实现了真正意义上的缓存数据同步,大幅度降低了数据延迟,减少了对前端总线的占用,性能表现不错,是目前双核心处理器上最先进的二级缓存架构。今后Intel的双核心处理器的二级缓存都会采用这种两个内核共享二级缓存的“Smart cache”共享缓存技术。

    AMD双核心处理器的二级缓存

      Athlon 64 X2 CPU的核心主要有Manchester和Toledo两种,他们的二级缓存都是CPU内部两个内核具有互相独立的二级缓存,其中,Manchester核心为每核心512KB,而Toledo核心为每核心1MB。处理器内部的两个内核之间的缓存数据同步是依靠CPU内置的System Request Interface(系统请求接口,SRI)控制,传输在CPU内部即可实现。这样一来,不但CPU资源占用很小,而且不必占用内存总线资源,数据延迟也比Intel的Smithfield核心和Presler核心大为减少,协作效率明显胜过这两种核心。不过,由于这种方式仍然是两个内核的缓存相互独立,从架构上来看也明显不如以Yonah核心为代表的Intel的共享缓存技术Smart Cache。

    一级缓存与二级缓存的比较

      L1 cache vs L2 Cache用于存储数据的缓存部分通常被称为RAM,掉电以后其中的信息就会消失。RAM又分两种,其中一种是静态RAM(SRAM);另外一种是动态RAM(DRAM)。前者的存储速度要比后者快得多,我们现在使用的内存一般都是动态RAM。CPU的L1级缓存通常都是静态RAM,速度非常的快,但是静态RAM集成度低(存储相同的数据,静态RAM的体积是动态RAM的6倍),而且价格也相对较为昂贵(同容量的静态RAM是动态RAM的四倍)。扩大静态RAM作为缓存是一个不太合算的做法,但是为了提高系统的性能和速度又必须要扩大缓存,这就有了一个折中的方法:在不扩大原来的静态RAM缓存容量的情况下,仅仅增加一些高速动态RAM做为L2级缓存。高速动态RAM速度要比常规动态RAM快,但比原来的静态RAM缓存慢,而且成本也较为适中。一级缓存和二级缓存中的内容都是内存中访问频率高的数据的复制品(映射),它们的存在都是为了减少高速CPU对慢速内存的访问。二级缓存是CPU性能表现的关键之一,在CPU核心不变化的情况下,增加二级缓存容量能使性能大幅度提高。而同一核心的CPU高低端之分往往也是在二级缓存上存在差异,由此可见二级缓存对CPU的重要性。CPU在缓存中找到有用的数据被称为命中,当缓存中没有CPU所需的数据时(这时称为未命中),CPU才访问内存。从理论上讲,在一颗拥有二级缓存的CPU中,读取一级缓存的命中率为80%。也就是说CPU一级缓存中找到的有用数据占数据总量的80%,剩下的20%从二级缓存中读取。由于不能准确预测将要执行的数据,读取二级缓存的命中率也在80%左右(从二级缓存读到有用的数据占总数据的16%)。那么还有的数据就不得不从内存调用,但这已经是一个相当小的比例了。目前的较高端CPU中,还会带有三级缓存,它是为读取二级缓存后未命中的数据设计的—种缓存,在拥有三级缓存的CPU中,只有约5%的数据需要从内存中调用,这进一步提高了CPU的效率,从某种意义上说,预取效率的提高,大大降低了生产成本却提供了非常接近理想状态的性能。除非某天生产技术变得非常强,否则内存仍会存在,缓存的性能递增特性也仍会保留。 CPU缓存与内存的关系既然CPU缓存能够在很大程度上提高CPU的性能,那么,有些朋友可能会问,是不是将来有可能,目前的系统内存将会被CPU取代呢?

      答案应该是否定的,首先,尽管CPU缓存的传输速率确实很高,但要完全取代内存的地位仍不可行,这主要是因为缓存只是内存中少部分数据的复制品,所以CPU到缓存中寻找数据时,也会出现找不到的情况(因为这些数据没有从内存复制到缓存中去),这时CPU还是会到内存中去找数据,与此同时系统的速度就慢了下来,不过CPU会把这些数据复制到缓存中去,以便下一次不用再到内存中去取。也即是说,随着缓存增大到一定程度,其对CPU性能的影响将越来越小,在性能比上来说,越来越不合算。就目前缓存容量、成本以及功耗表现来看,还远远无法与内存抗衡,另外从某种意义上来说,内存也是CPU缓存的一种表现形式,只不过在速率上慢很多,然而却在容量、功耗以及成本方面拥有巨大优势。如果内存在将来可以做到足够强的话,反而很有取代CPU缓存的可能。 缓存的读写算法同样重要即便CPU内部集成的缓存数据交换能力非常强,也仍需要对调取数据做一定的筛选。这是因为随着时间的变化,被访问得最频繁的数据不是一成不变的,也就是说,刚才还不频繁的数据,此时已经需要被频繁的访问,刚才还是最频繁的数据,现在又不频繁了,所以说缓存中的数据要经常按照一定的算法来更换,这样才能保证缓存中的数据经常是被访问最频繁的。命中率算法中较常用的“最近最少使用算法”(LRU算法),它是将最近一段时间内最少被访问过的行淘汰出局。因此需要为每行设置一个计数器,LRU算法是把命中行的计数器清零,其他各行计数器加1。当需要替换时淘汰行计数器计数值最大的数据行出局。这是一种高效、科学的算法,其计数器清零过程可以把一些频繁调用后再不需要的数据淘汰出缓存,提高缓存的利用率。 高速缓存做为CPU不可分割的一部分,已经融入到性能提升的考虑因素当中,伴随生产技术的进一步发展,缓存的级数还将增加,容量也会进一步提高。作为CPU性能助推器的高速缓存,仍会在成本和功耗控制方面发挥巨大的优势,而性能方面也会取得长足的发展。

    三级缓存

      三级缓存是为读取二级缓存后未命中的数据设计的—种缓存,在拥有三级缓存的CPU中,只有约5%的数据需要从内存中调用,这进一步提高了CPU的效率。

      其实最早的L3缓存被应用在AMD发布的K6-III处理器上,当时的L3缓存受限于制造工艺,并没有被集成进芯片内部,而是集成在主板上。在只能够和系统总线频率同步的L3缓存同主内存其实差不了多少。后来使用L3缓存的是英特尔为服务器市场所推出的Itanium(Itanium 安腾 )处理器。接着就是P4EE(Extreme Edition)和至强MP。Intel还打算推出一款9MB L3缓存的Itanium2处理器,和以后24MB L3缓存的双核心Itanium2处理器。

      但基本上L3缓存对处理器的性能提高显得不是很重要,比方配备1MB L3缓存的Xeon MP处理器却仍然不是Opteron的对手,由此可见前端总线的增加,要比缓存增加带来更有效的性能提升。

    展开全文
  • 基于GEMS的三级Cache一致性协议的设计和实现,武越川,李艳华,分析了cache一致性协议的工作机理,定义了cache在不同事件驱动下的状态转换过程和相关的操作,在MOESI基础上设计了个三级独立Cache
  • 1. 简介 现在android应用中不可避免的要使用图片,有些图片...在当前的状况下,对于非wifi用户来说,流量还是很贵的,个很耗流量的应用,其用户数量肯定要受到影响。当然,我想,向百度美拍这样的应用,必然也有其

    1. 简介

    现在android应用中不可避免的要使用图片,有些图片是可以变化的,需要每次启动时从网络拉取,这种场景在有广告位的应用以及纯图片应用(比如百度美拍)中比较多。

    现在有一个问题:假如每次启动的时候都从网络拉取图片的话,势必会消耗很多流量。在当前的状况下,对于非wifi用户来说,流量还是很贵的,一个很耗流量的应用,其用户数量级肯定要受到影响。当然,我想,向百度美拍这样的应用,必然也有其内部的图片缓存策略。总之,图片缓存是很重要而且是必须的。

     

    2.图片缓存的原理

    实现图片缓存也不难,需要有相应的cache策略。这里我采用 内存-文件-网络 三层cache机制,其中内存缓存包括强引用缓存和软引用缓存(SoftReference),其实网络不算cache,这里姑且也把它划到缓存的层次结构中。当根据url向网络拉取图片的时候,先从内存中找,如果内存中没有,再从缓存文件中查找,如果缓存文件中也没有,再从网络上通过http请求拉取图片。在键值对(key-value)中,这个图片缓存的key是图片url的hash值,value就是bitmap。所以,按照这个逻辑,只要一个url被下载过,其图片就被缓存起来了。


    关于Java中对象的软引用(SoftReference),如果一个对象具有软引用,内存空间足够,垃 圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高 速缓存。使用软引用能防止内存泄露,增强程序的健壮性。  


    从代码上来说,采用一个ImageManager来负责图片的管理和缓存,函数接口为public void loadBitmap(String url, Handler handler) ;其中url为要下载的图片地址,handler为图片下载成功后的回调,在handler中处理message,而message中包含了图片的信息以及bitmap对象。ImageManager中使用的ImageMemoryCache(内存缓存)、ImageFileCache(文件缓存)以及LruCache(最近最久未使用缓存)会在后续文章中介绍。


    3.代码ImageManager.java

     

    /*
     * 图片管理
     * 异步获取图片,直接调用loadImage()函数,该函数自己判断是从缓存还是网络加载
     * 同步获取图片,直接调用getBitmap()函数,该函数自己判断是从缓存还是网络加载
     * 仅从本地获取图片,调用getBitmapFromNative()
     * 仅从网络加载图片,调用getBitmapFromHttp()
     * 
     */
    
    public class ImageManager implements IManager
    {
    	private final static String TAG = "ImageManager";
    	
    	private ImageMemoryCache imageMemoryCache; //内存缓存
    	
    	private ImageFileCache   imageFileCache; //文件缓存
    	
    	//正在下载的image列表
    	public static HashMap<String, Handler> ongoingTaskMap = new HashMap<String, Handler>();
    	
    	//等待下载的image列表
    	public static HashMap<String, Handler> waitingTaskMap = new HashMap<String, Handler>();
    	
    	//同时下载图片的线程个数
    	final static int MAX_DOWNLOAD_IMAGE_THREAD = 4;
    	
    	private final Handler downloadStatusHandler = new Handler(){
    		public void handleMessage(Message msg)
    		{
    			startDownloadNext();
    		}
    	};
    	
    	public ImageManager()
    	{
    		imageMemoryCache = new ImageMemoryCache();
    		imageFileCache = new ImageFileCache();
        }
    	
        /**
         * 获取图片,多线程的入口
         */
        public void loadBitmap(String url, Handler handler) 
        {
            //先从内存缓存中获取,取到直接加载
            Bitmap bitmap = getBitmapFromNative(url);
            
            if (bitmap != null)
            {
                Logger.d(TAG, "loadBitmap:loaded from native");
            	Message msg = Message.obtain();
                Bundle bundle = new Bundle();
                bundle.putString("url", url);
                msg.obj = bitmap;
                msg.setData(bundle);
                handler.sendMessage(msg);
            } 
            else
            {
            	Logger.d(TAG, "loadBitmap:will load by network");
            	downloadBmpOnNewThread(url, handler);
            }
        }
        
        /**
         * 新起线程下载图片
         */
        private void downloadBmpOnNewThread(final String url, final Handler handler)
        {
    		Logger.d(TAG, "ongoingTaskMap'size=" + ongoingTaskMap.size());
        	
    		if (ongoingTaskMap.size() >= MAX_DOWNLOAD_IMAGE_THREAD) 
    		{
    			synchronized (waitingTaskMap) 
    			{
    				waitingTaskMap.put(url, handler);
    			}
    		} 
    		else 
    		{
    			synchronized (ongoingTaskMap) 
    			{
    				ongoingTaskMap.put(url, handler);
    			}
    
    			new Thread() 
    			{
    				public void run() 
    				{
    					Bitmap bmp = getBitmapFromHttp(url);
    
    					// 不论下载是否成功,都从下载队列中移除,再由业务逻辑判断是否重新下载
    					// 下载图片使用了httpClientRequest,本身已经带了重连机制
    					synchronized (ongoingTaskMap) 
    					{
    						ongoingTaskMap.remove(url);
    					}
    					
    					if(downloadStatusHandler != null)
    					{
    						downloadStatusHandler.sendEmptyMessage(0);
    					
    					}
    
    					Message msg = Message.obtain();
    					msg.obj = bmp;
    					Bundle bundle = new Bundle();
    					bundle.putString("url", url);
    					msg.setData(bundle);
    					
    					if(handler != null)
    					{
    						handler.sendMessage(msg);
    					}
    
    				}
    			}.start();
    		}
    	}
    
        
    	/**
         * 依次从内存,缓存文件,网络上加载单个bitmap,不考虑线程的问题
         */
    	public Bitmap getBitmap(String url)
    	{
    	    // 从内存缓存中获取图片
    	    Bitmap bitmap = imageMemoryCache.getBitmapFromMemory(url);
    	    if (bitmap == null) 
    	    {
    	        // 文件缓存中获取
    	    	bitmap = imageFileCache.getImageFromFile(url);
    	        if (bitmap != null) 
    	        {	            
    	        	// 添加到内存缓存
    	        	imageMemoryCache.addBitmapToMemory(url, bitmap);
    	        } 
    	        else 
    	        {
    	            // 从网络获取
    	        	bitmap = getBitmapFromHttp(url);
    	        }
    	    }
    	    return bitmap;
    	}
    	
    	/**
    	 * 从内存或者缓存文件中获取bitmap
    	 */
    	public Bitmap getBitmapFromNative(String url)
    	{
    		Bitmap bitmap = null;
    		bitmap = imageMemoryCache.getBitmapFromMemory(url);
    		
    		if(bitmap == null)
    		{
    			bitmap = imageFileCache.getImageFromFile(url);
    			if(bitmap != null)
    			{
    				// 添加到内存缓存
    				imageMemoryCache.addBitmapToMemory(url, bitmap);
    			}
    		}
    		return bitmap;
    	}
    	
    	/**
    	 * 通过网络下载图片,与线程无关
    	 */
    	public Bitmap getBitmapFromHttp(String url)
    	{
    		Bitmap bmp = null;
    		
    		try
    		{
    			byte[] tmpPicByte = getImageBytes(url);
    	
    			if (tmpPicByte != null) 
    			{
    				bmp = BitmapFactory.decodeByteArray(tmpPicByte, 0,
    						tmpPicByte.length);
    			}
    			tmpPicByte = null;
    		}
    		catch(Exception e)
    		{
    			e.printStackTrace();
    		}
    		
    		if(bmp != null)
    		{
    			// 添加到文件缓存
    			imageFileCache.saveBitmapToFile(bmp, url);
    			// 添加到内存缓存
    			imageMemoryCache.addBitmapToMemory(url, bmp);
    		}
    
    		return bmp;
    	}
    	
    	/**
    	 * 下载链接的图片资源
    	 * 
    	 * @param url
    	 *            
    	 * @return 图片
    	 */
    	public byte[] getImageBytes(String url) 
    	{
    		byte[] pic = null;
    		if (url != null && !"".equals(url)) 
    		{
    			Requester request = RequesterFactory.getRequester(
    					Requester.REQUEST_REMOTE, RequesterFactory.IMPL_HC);
    			// 执行请求
    			MyResponse myResponse = null;
    			MyRequest mMyRequest;
    			mMyRequest = new MyRequest();
    			mMyRequest.setUrl(url);
    			mMyRequest.addHeader(HttpHeader.REQ.ACCEPT_ENCODING, "identity");
    			InputStream is = null;
    			ByteArrayOutputStream baos = null;
    			try {
    				myResponse = request.execute(mMyRequest);
    				is = myResponse.getInputStream().getImpl();
    				baos = new ByteArrayOutputStream();
    				byte[] b = new byte[512];
    				int len = 0;
    				while ((len = is.read(b)) != -1) 
    				{
    					baos.write(b, 0, len);
    					baos.flush();
    				}
    				pic = baos.toByteArray();
    				Logger.d(TAG, "icon bytes.length=" + pic.length);
    
    			} 
    			catch (Exception e3) 
    			{
    				e3.printStackTrace();
    				try 
    				{
    					Logger.e(TAG,
    							"download shortcut icon faild and responsecode="
    									+ myResponse.getStatusCode());
    				} 
    				catch (Exception e4) 
    				{
    					e4.printStackTrace();
    				}
    			} 
    			finally 
    			{
    				try 
    				{
    					if (is != null) 
    					{
    						is.close();
    						is = null;
    					}
    				} 
    				catch (Exception e2) 
    				{
    					e2.printStackTrace();
    				}
    				try 
    				{
    					if (baos != null) 
    					{
    						baos.close();
    						baos = null;
    					}
    				} 
    				catch (Exception e2) 
    				{
    					e2.printStackTrace();
    				}
    				try 
    				{
    					request.close();
    				} 
    				catch (Exception e1) 
    				{
    					e1.printStackTrace();
    				}
    			}
    		}
    		return pic;
    	}
    	
    	/**
    	 * 取出等待队列第一个任务,开始下载
    	 */
    	private void startDownloadNext()
    	{
    		synchronized(waitingTaskMap)
    		{	
    			Logger.d(TAG, "begin start next");
    			Iterator iter = waitingTaskMap.entrySet().iterator(); 
    		
    			while (iter.hasNext()) 
    			{
    				
    				Map.Entry entry = (Map.Entry) iter.next();
    				Logger.d(TAG, "WaitingTaskMap isn't null,url=" + (String)entry.getKey());
    				
    				if(entry != null)
    				{
    					waitingTaskMap.remove(entry.getKey());
    					downloadBmpOnNewThread((String)entry.getKey(), (Handler)entry.getValue());
    				}
    				break;
    			}
    		}
    	}
    	
    	public String startDownloadNext_ForUnitTest()
    	{
    		String urlString = null;
    		synchronized(waitingTaskMap)
    		{
    			Logger.d(TAG, "begin start next");
    			Iterator iter = waitingTaskMap.entrySet().iterator(); 
    		
    			while (iter.hasNext()) 
    			{
    				Map.Entry entry = (Map.Entry) iter.next();
    				urlString = (String)entry.getKey();
    				waitingTaskMap.remove(entry.getKey());
    				break;
    			}
    		}
    		return urlString;
    	}
    	
    	/**
    	 * 图片变为圆角
    	 * @param bitmap:传入的bitmap
    	 * @param pixels:圆角的度数,值越大,圆角越大
    	 * @return bitmap:加入圆角的bitmap
    	 */
    	public static Bitmap toRoundCorner(Bitmap bitmap, int pixels) 
    	{ 
            if(bitmap == null)
            	return null;
            
    		Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888); 
            Canvas canvas = new Canvas(output); 
     
            final int color = 0xff424242; 
            final Paint paint = new Paint(); 
            final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); 
            final RectF rectF = new RectF(rect); 
            final float roundPx = pixels; 
     
            paint.setAntiAlias(true); 
            canvas.drawARGB(0, 0, 0, 0); 
            paint.setColor(color); 
            canvas.drawRoundRect(rectF, roundPx, roundPx, paint); 
     
            paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); 
            canvas.drawBitmap(bitmap, rect, rect, paint); 
     
            return output; 
        }
    	
    	public byte managerId() 
    	{
    		return IMAGE_ID;
    	}
    }

    展开全文
  • 本文主要记录java项目集成J2Cache并以ehcache作为一级缓存,redis作为二级缓存的配置过程。(以下内容仅个人观点) 首先介绍下已有项目情况,已有项目为ssm框架,已集成ehcache功能即目前项目后台已使用ehcache缓存...
  • cache

    千次阅读 2018-11-01 17:39:40
    CPU,内存和cache之间的关系 和 cache的操作 https://blog.csdn.net/vanbreaker/article/details/7470830 cache和内存的关联方式(associativity) https://blog.csdn.net/vanbreaker/article/details/7475093 ...
  • Hibernate 一级缓存(First-level cache)和二级缓存(second-level cache) 介绍分别是什么?First-level cache: First-level cache always Associates with the Session object. Hibernate uses this cache by default...
  • Cache

    千次阅读 2016-09-01 23:14:04
    强制性失效 (Compulsory miss): 当第一次访问一个块时,该块不在 Cache中, 需从下一级存储中调入 Cache, 这就是强制性失效。这种失效也称为冷启动失效,或首次访问失效。(增加块大小,预取) 容量失效 (Capacity miss...
  • 当前有四个工具: RedisCache , TairCache (在github上不是开源的), CaffeineCache (在内存中),个简单的LinkedHashMapCache (在内存中)。 JetCache的全部功能: 通过一致的缓存API操作缓存。 使用带...
  • 为了提高嵌入式系统中Cache的使用效率,针对...均衡考虑指令和数据Cache需求,动态地调整一级Cache的容量和配置。采用滑动Cache结构,不但降低了一级Cache的动态和静态泄漏功耗,而且还降低了整个处理器的动态功耗。
  • verilog编写的MIPS五级流水线,实现四十余条指令,使用512B的一级数据cache(高速缓存)。附带测试程序与说明文档。
  • 一套cache仿真Verilog代码,很有用
  • MyBatis二缓存Cache Hit Ratio始终等于0问题描述问题排查最终结论 问题描述 在MyBatis中,不同SqlSession作用域中开启了两个相同的查询操作。但是在控制台的输出中一直显示没有命中缓存,持续进行SQL查询操作。 ...
  • ACache类似于SharedPreferences,但是比SharedPreferences功能更加强大,SharedPreferences只能保存一些基本数据类型、Serializable、Bundle等数据, 而Acache可以缓存如下数据: 普通的字符串、JsonObject、...
  • 如果想很好地理解下面的故事,请参看我半年前写的两篇博文:android中图片的三级cache策略(内存、文件、网络)  和 android中左右滑屏的实现(广告位banner组件)。当时没有发上来是由于如下几点原因:首先...
  • 细说 ASP.NET Cache 及其高级用法

    千次阅读 2016-04-25 09:33:34
    http://www.cnblogs.com/fish-li/archive/2011/12/27/2304063.html开始Cache的基本用途Cache的定义Cache常见用法Cache类的特点缓存项的过期时间缓存项的依赖关系 - 依赖其它缓存项缓存项的依赖关系 - 文件依赖...
  • java两缓存框架J2cache

    千次阅读 2018-07-26 13:41:28
    一级缓存使用 Ehcache,第二级缓存使用 Redis 。由于大量的缓存读取会导致 L2 的网络成为整个系统的瓶颈,因此 L1 的目标是降低对 L2 的读取次数。该缓存框架主要用于集群环境中。单机也可使用,用于避免应用...
  • Cache简介(

    千次阅读 多人点赞 2018-01-23 18:44:21
    cache是干啥的? 在以前,CPU的主频比较慢,CPU和内存DRAM之间速度差别不是很大,存储...cache就出来了,它类似与个第三方。位于内存和CPU之间,速度非常快,所以CPU就把数据直接写入cache,然后CPU就可以干其他的了
  • 如果想很好地理解下面的故事,请参看我半年前写的两篇博文:android中图片的三级cache策略(内存、文件、网络)  和 android中左右滑屏的实现(广告位banner组件),还有昨天晚上写的android中图片的三级cache...
  • springboot1.x基于spring注解实现J2Cache两级缓存集成,一级缓存:ehcache,二级缓存:redis,代码可直接运行(根据项目中的README.md提示)
  • 系统为了提高数据访问速度,先将数据加载到redis缓存...因此,可以在redis前增加本地一级缓存,本地一级缓存和系统应用在同一个JVM内,这样速度最快,redis退居二线当作二级缓存。每次请求先从一级缓存读取数据,...
  • Cache 的基本概念与工作原理 背景知识 随着 CPU 技术的飞速发展,常用的处理器飞奔在越来越高的频率之上,虽然处理器的速度越来越快,但是与之相匹配的存储器的速度却没有获得相应的提升,这大大限制了 CPU 的处理...
  • Linux 3.6内核去掉了路由cache的支持,这件事众口难调。也许你会记得路由cache给你带来的各种好处,也许...如果你不服,那大可不必理会这些缺陷,将路由cache重新移回你自己的版本即是,然而我并不觉得这是个好的方案
  • 多级Cache原理

    千次阅读 2017-05-05 16:31:31
    多级Cache技术,利用使用一个大的二级Cache来处理一级Cache的缺失,从而降低缺失代价。 二级Cache已经逐渐普及,这是因为设计者发现由于硅的局限性以及高时钟平率的要求,一级Cache的容量已经无法更大了。 二级Cache...
  • 1.添加依赖 <!-- 添加ehcache支持 --> <dependency> <groupId>org.springframework.boot</groupId>...spring-boot-starter-cache</artifactId> </dependenc...
  • MyBatis 二缓存cache官方解释

    千次阅读 2017-07-28 11:38:38
    MyBatis 包含个非常强大的查询缓存特性,它可以非常方便地配置和定制。MyBatis 3 中的缓存实现的很多改进都已经实现了,使得它更加强大而且易于配置。 默认情况下是没有开启缓存的,除了局部的 sessi
  • guava cache

    千次阅读 2017-07-12 11:57:07
    但比ConcurrentHashMap提供了更多的功能,比如缓存的回收(但是需要注意的是这种缓存回收机制并不是guava cache主动回收的,而是被动的基于缓存的读写进行回收的,这样的实现机制也是guava cache轻量个原因之...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 289,501
精华内容 115,800
关键字:

一级cache