CPU的一、二、三级缓存

这篇具有很好参考价值的文章主要介绍了CPU的一、二、三级缓存。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在Java并发编程中,我们经常会遇到共享变量的读写问题,关于这类问题我们经常会说到原子性、可见性、有序性这三大特性,再进一步会了解到总线和CPU的一、二、三级缓存。关于这三个级别的缓存网上文章介绍比较多,今天我们这篇文章,算是知识梳理与记录,也是总结与强化。

前言

本文并非是CPU缓存知识的大杂烩、大汇总,关于CPU三个级别缓存的讲解,如果细致地说,一篇文章可能说不清楚。同时,介绍一些比较“虚”的知识点,很多小伙伴并不感兴趣,比如CPU缓存的发展史,这就要涉及不同架构、不同型号的CPU的知识,这样罗列下来意义也不大。

所以,本篇文章重在讲解干货,让人一目了然,之后便能铭记于心,如果需要面试也能说得明白。

一、概述

下面这段文字来自百科:

CPU高级缓存,(英语:CPU Cache,在本文中简称缓存)是用于减少处理器访问内存所需平均时间的部件。在金字塔式存储体系中它位于自顶向下的第二层,仅次于CPU寄存器。其容量远小于内存,但速度却可以接近处理器的频率。

当处理器发出内存访问请求时,会先查看缓存内是否有请求数据。如果存在(命中),则不经访问内存直接返回该数据;如果不存在(失效),则要先把内存中的相应数据载入缓存,再将其返回处理器。

缓存之所以有效,主要是因为程序运行时对内存的访问呈现局部性(Locality)特征。这种局部性既包括空间局部性(Spatial Locality),也包括时间局部性(Temporal Locality)。有效利用这种局部性,缓存可以达到极高的命中率。

在处理器看来,缓存是一个透明部件。因此,程序员通常无法直接干预对缓存的操作。但是,确实可以根据缓存的特点对程序代码实施特定优化,从而更好地利用缓存。

CPU高速缓存我们一般称之为CPU缓存,或者缓存。通过上面这段文字,我们大致可以得出以下几点结论:

  1. 缓存是了减少处理器访问内存所需的时间。
  2. 缓存容量远小于内存,速度远大于内存,非常接近处理器。
  3. 处理器向内存发出访问请求时,先查看缓存,缓存命中则不经过内存直接返回数据;缓存未命中,则先把内存中数据再入缓存再返回处理器。这个原理与Redis和数据库的缓存使用操作方式是一致的。
  4. 有效利用局部性特征可以极大地提高缓存命中率
  5. 开发人员无法直接干预对缓存的操作,但是可以通过程序代码来优化缓存命中率。

CPU在缓存中找到有用的数据被称为命中,当缓存中没有CPU所需的数据时(这时称为未命中),CPU才访问内存。

CPU缓存的容量比内存小的多但是交换速度却比内存要快得多。缓存的出现主要是为了解决CPU运算速度与内存读写速度不匹配的矛盾,因为CPU运算速度要比内存读写速度快很多,这样会使CPU花费很长时间等待数据到来或把数据写入内存。 

二、CPU缓存简介

一级缓存的起源针对内存的速度瓶颈,英特尔为80386设计了高速缓存(Cache),采取预读内存的方法来缓解这个速度瓶颈。本来最初的设计,80386将内置L1 Cache,但由于工艺、成本、工期等等方面的限制,80386最后并没有内置L1 Cache,而是将专门开发的L1 Cache芯片放置在CPU之外的主板上,但从此以后,Cache就和CPU成为了如影随形的东西。

简单来说,一级缓存是英特尔针对内存的速度瓶颈,采取预读内存方法来设计的高速缓存。

一级缓存最初是放置在CPU之外的主板上的,后来随着工艺等方面的提高,一级缓存已经内置到CPU中内部并与CPU同速运行。

一级缓存内置在CPU内部,直接与CPU数据总线相连,传输速度接近于CPU处理速度。

这就是一级缓存。

用于存储数据的缓存部分通常被称为RAM,掉电以后其中的信息就会消失。RAM又分两种,其中一种是静态RAM(SRAM);另外一种是动态RAM(DRAM)。前者的存储速度要比后者快得多,我们现在使用的内存一般都是动态RAM。

CPU的L1级缓存通常都是静态RAM,速度非常的快,但是静态RAM集成度低(存储相同的数据,静态RAM的体积是动态RAM的6倍),而且价格也相对较为昂贵(同容量的静态RAM是动态RAM的四倍)。扩大静态RAM作为缓存是一个不太合算的做法,但是为了提高系统的性能和速度又必须要扩大缓存,这就有了一个折中的方法:在不扩大原来的静态RAM缓存容量的情况下,仅仅增加一些高速动态RAM做为L2级缓存。

二级缓存,它是为了协调一级缓存和内存之间的速度。

这就是二级缓存。

三级缓存是为读取二级缓存后未命中的数据设计的—种缓存,在拥有三级缓存的CPU中,只有约5%的数据需要从内存中调用,这进一步提高了CPU的效率。其运作原理在于使用较快速的储存装置保留一份从慢速储存装置中所读取数据且进行拷贝,当有需要再从较慢的储存体中读写数据时,缓存(cache)能够使得读写的动作先在快速的装置上完成,如此会使系统的响应较为快速。

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

英特尔公司在推出Pentium 4处理器时,用新增的一种一级追踪缓存替代指令缓存,容量为12KμOps,表示能存储12K条微指令。

注意:

此时如果说L1的大小就不能使用L1d和L1i相加得出L1的大小,我们分别说数据缓存大小是多少,指令缓存是多少。

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

三、CPU缓存详解

3.1 一级缓存

一级缓存(Level 1 Cache)简称L1 Cache,位于CPU内核的旁边,是与CPU结合最为紧密的CPU缓存,也是历史上最早出现的CPU缓存。

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

二者分别用来存放数据以及对执行这些数据的指令进行即时解码,而且两者可以同时被CPU访问,减少了争用Cache所造成的冲突,提高了处理器效能。目前大多数CPU的一级数据缓存和一级指令缓存具有相同的容量。

缓存的出现主要是为了解决CPU运算速度与内存读写速度不匹配的矛盾。

3.2 L1、L2、L3大小对比

在服务器上我们可以使用命令lscpu来查看CPU的情况:

CPU的一、二、三级缓存

 上图红框分别代表一级数据缓存、一级指令缓存、二级缓存和三级缓存以及它们对应的大小

从图中我们也可以看到一级缓存非常小,只有几十kb,同时L1d和L1i的大小是相同的(这不是绝对的,但是我们一般可以这么说)。

二级缓存和三级缓存大小依次递增,当然它们之间的访问速度却是依次递减的。

下图是一张CPU与各个硬件之间速度与大小递进关系图。

CPU的一、二、三级缓存

通过上图我们可以得出以下结论:

  1. L1、L2、L3都是SRAM,即Static RAM,静态RAM,速度很快
  2. L1、L2、L3速度依次递减,容量依次递增,价格依次递减
  3. L1、L2、L3都是集成在CPU内部
  4. 我们常用的内存是DRAM,即dynamic RAM,动态RAM,速度较慢

L1的大小一般在4KB到64KB之间,像我们上面图中列出的L1d和L1i分别为32K,加在一起也就64K。一些高端CPU大小可以达到1-2MB。

L2一般以MB为单位,但其大小通常在 1024KB 到 8MB 之间,上图我们这个就是1024KB,也就是1MB。

说明:

有的地方说是256KB到8MB之间,说法不一,不过这个也不是关键,两种说法皆可。但是通常分为128KB、256KB、512KB、1MB、2MB等。

L3一般也是以MB为单位,大小通常在4MB到50MB之间,上图我们的就是36608/1024=35.75MB。

像公司一般的CPU配置也就是上面我的这种,差距不大,但是有一些可能就比较大了,比如做数仓、数据迁移的ETL服务器,就比较大了。不但CPU比较大,内存都几十几百GB。如下图所示。

CPU的一、二、三级缓存

3.3 二级缓存详解

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

L1是一级缓存,通常内建于微处理芯片(Chip)中。比如,IntelMMX微处理器(microprocessor)本身是带有一个有32Kb的一级缓存。

L2(就是二级)缓存是在独立芯片(有可能是在一个扩展卡上)。

有这样一段说法:

从理论上讲,在一颗拥有二级缓存的CPU中,读取一级缓存的命中率为80%。也就是说CPU一级缓存中找到的有用数据占数据总量的80%,剩下的20%从二级缓存中读取。

由于不能准确预测将要执行的数据,读取二级缓存的命中率也在80%左右(从二级缓存读到有用的数据占总数据的16%)。那么还有的数据就不得不从内存调用,但这已经是一个相当小的比例了。

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

我们大致了解到它们之间数据命中的概率即可,也说明了二级缓存的重要性。

3.3 三级缓存

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

其运作原理在于使用较快速的储存装置保留一份从慢速储存装置中所读取数据且进行拷贝,当有需要再从较慢的储存体中读写数据时,缓存(cache)能够使得读写的动作先在快速的装置上完成,如此会使系统的响应较为快速。

早期的三级缓存也是外置的,CPU升级之后都是内置在CPU中的。

L3缓存的应用可以进一步降低内存延迟,同时提升大数据量计算时处理器的性能。

降低内存延迟和提升大数据量计算能力对游戏软件都很有帮助。而在服务器领域增加L3缓存在性能方面仍然有显著的提升。如具有较大L3缓存的配置利用物理内存会更有效,故它比较慢的磁盘I/O子系统可以处理更多的数据请求。具有较大L3缓存的处理器提供更有效的文件系统缓存行为及较短消息和处理器队列长度。

不过对于一般的家用PC来说,三级缓存的作用不大,只是起到一个辅助作用。三级缓存主要用途还是在游戏上和服务器上。文章来源地址https://www.toymoban.com/news/detail-413017.html

到了这里,关于CPU的一、二、三级缓存的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Mybatis缓存机制(一级缓存、二级缓存、三级缓存)

    缓存就是内存中的数据,常常来自对数据库查询结果的保存。 使用缓存,我们可以避免频繁与数据库进行交互,从而提高响应速度。 Mybatis的缓存分为一级缓存、二级缓存、三级缓存。 一级缓存: 作用域是同一个 SqlSession,在同一个 sqlSession 中两次执行相同的 sql 语句, 第一

    2024年02月05日
    浏览(48)
  • keep-alive缓存三级及三级以上路由

    需求:需要缓存这个出入记录,当tab切换时不重新加载,当刷新页面时,或把这个关闭在重新打开时重新加载如图: (我这里用的是芋道源码的前端框架) 1、include 包含页面组件name的这些组件页面,会被缓存起来 2、exclude 除了这些name以外的页面组件,会被缓存起来 3、没有

    2024年02月09日
    浏览(41)
  • Spring 的三级缓存机制

    Spring 的三级缓存机制 Spring 的三级缓存机制是解决循环依赖的关键 。 Spring 框架为了解决循环依赖问题,设计了一套三级缓存机制。这三级缓存分别是: 一级缓存 singletonObjects :这是最常规的缓存,用于存放完全初始化好的 bean。如果某个 bean 已经在这个缓存中,则直接返回

    2024年04月26日
    浏览(34)
  • MyBatis三级缓存详解

    MyBatis作为一款优秀的持久层框架,在处理数据库操作时提供了丰富的功能,其中之一就是三级缓存。本篇博文将深入介绍MyBatis的三级缓存,通过详细的例子带你了解三级缓存的使用和原理。 MyBatis的三级缓存是指在执行SQL语句时,可以将查询的结果缓存在三个不同的范围内,

    2024年01月18日
    浏览(39)
  • Spring三级缓存

    重点AOP作用于代理对象,方法中调用其余方法的注解需要将本类注入进去。 当AService出现了循环依赖的情况下----AService提前进行AOP 0.creatingSet.add(\\\'aService\\\') 1.class -实例化得到Aservice原始对象--提前进行AOP---AService代理对象---Mapbe anMap, Aservice代理对象 2.给bService属性赋值---从单例池

    2024年01月21日
    浏览(39)
  • 【Spring】三级缓存

    结合文章:循环依赖 测试代码如下: 执行refresh 方法 执行finishBeanFactoryInitialization 方法 执行preInstantiateSingletons 方法 实际上就是通过 doGetBean ,先进行 bean-a 的初始化 去缓存查看时候有 bean - a 实际上就是通过双重校验锁,去查看一级缓存中是否有 bean-a 并且没有在创建中 ,所

    2024年02月21日
    浏览(84)
  • 论 spring 的三级缓存

    bean的生命周期 bean 的生命周期 这个问题只是出现在spring 容器的机制中,其实我们代码中很简单就解决了。 假设A 对象里需要注入一个B属性,B 对象里面需要注入一个A 属性。根据Bean 的生命周期,先实例化A 的实例,然后进行A属性的填充,这时就需要一个B的对象,在通过

    2024年02月05日
    浏览(39)
  • Spring 三级缓存

    一级缓存 SingletonObject 存放完全初始化好的bean,该缓存取出来的bean 可以直接使用 二级缓存 earlySingletonObject 提前曝光单单例对象的cache,存放原始对象bean(尚未填充属性),用于解决循环依赖。 三级缓存 SingletonFacotoies单例对象工厂的cache,存放 ObjectFactory对象,用于解决循环依赖。

    2024年02月08日
    浏览(56)
  • Spring三级缓存详解

    Spring三级缓存 是为了解决 对象间的循环依赖 问题。 A依赖B,B依赖A,这就是一个简单的循环依赖。 我们来先看看三级缓存的源码。 (1)查看“获取Bean”的源码,注意getSingleton()方法。 (2)“添加到第1级缓存”的源码: (3)“添加到第3级缓存”的源码: (4)“创建Be

    2024年02月07日
    浏览(61)
  • 我们在追求什么?以及我们将通往何方?记录AIGC共建者大会的一次演讲

    ‍‍ ​ 下一秒: 这个世界真如我们所见那样吗? 大家好,我是shadow。在特赞主办的AIGC创建者大会上,我分享了作为多重职业身份所从事的一些有意思的事情: 作为创作者 ,生成式人工智能展示了TA的才华,让每一位普通人,拥有了一支富有创意的文案和视觉团队。 AI的想

    2024年02月13日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包