为什么要有缓存?

再说到cpu的缓存一致性前提下,需要了解到为什么会有缓存:
众所周知,cpu是用来计算和处理数据的,本身并不存储数据,数据都是放在内存或者硬盘中,而内存与cpu之间是存在距离的,如果说cpu目前要进行一次计算,那么就需要先从内存将数据取出再进行计算,而内存和cpu是存在速度差异的,在随着现代技术的发展,嵌入到cpu上的晶体管越来越多,那么就造成了cpu的计算和处理能力越来越强,这样就更加凸显了这个弊端,cpu在一次处理中更多的时间是在等待内存中的数据到来,这样的情况是我们人类是不能容忍的(我把你创造出来就是干活的,你可不能闲着);

在这样的需求驱动下,就需要提高cpu的利用率。思路就是在cpu和内存之间加一层缓冲(缓存,此处忽略三级缓存的差异,统称为缓存),因为cpu加载缓存中的数据比较快,所以就提高了cpu的利用率,那么现在cpu在处理数据的时候就会先从缓存中查找,找不到就去内存中找,但是这次cup从内存中不但是加载本次需要处理的数据,而且会将本次处理数据周围空间的数据也进行加载(这涉及时间局部性,空间局部性)因为cpu会觉得我下次要加载的数据肯定会在本次处理数据的周围,那么下次我就不需要再来读取内存了,直接在缓存中找就可以啦;

所以目前的架构变成了这个样子:

缓存的利和弊

现在cpu再加入了缓存之后如虎添翼,cpu的利用率大大提高了(基本实现了007);
■ 优点:加快了cpu的处理能力,提高了cpu的利用率
■ 缺点:
● 在单核cpu的的系统中,基本是没缺点的
● 那么在多核cpu的情况下会有什么问题呢?首先需要知道一个知识点(敲黑板啦),为了避免多个cpu共用一个缓存,造成多个cpu掐架,那么给每个cpu都分配一个女朋友,不对,是分配一个缓存,各自用各自的缓存,那么就会造成一个问题:数据不一致问题;

数据不一致问题

先来看一段代码:
下面的这段代码,执行后会发现,有一定概率 线程1 会一直在运行,
代码描述:
目前是开启了两个线程,那现在这两个线程各自由一个cpu所处理,而线程退出的条件是:公有变量COUNTER大于5,目前这个COUNTER值的增加是在 线程2中进行的;

执行流程:

  1. cpu1将线程1加载到自己的缓存,包括COUNTER 的值=0
  2. cpu2将线程2加载自己的缓存,包括COUNTER 的值=0
  3. 目前因为cpu1和cpu2将数据都各自拷贝了一份到自己的缓存中,那么cpu2对COUNTER的值进行增加操作,对于cpu1是无法感知的;所以cpu1会在while 一直出不来

解决:
对于这样因为缓存不一致导致的bug,在Java层面,我们可以使用 volatile 关键字来进行解决,这种在多cpu环境下变量的可见性问题,被volatile关键字标注的变量,当此变量的值被更改后,会强制将更改后的值刷新会内存,并失效各个cpu中的缓存的变量;

package com.zy.util;import java.util.regex.Pattern;/*** @Author: hu.chen* @Description:* @DateTime: 2021/12/2 2:54 下午**/
public class Test {//    volatileprivate static int COUNTER = 0;public static void main(String[] args) {new ChangeListener().start();new ChangeMaker().start();}static class ChangeListener extends Thread {@Overridepublic void run() {int threadValue = COUNTER;while (threadValue < 5) {if (threadValue != COUNTER) {System.out.println("线程1 : " + COUNTER + "");threadValue = COUNTER;}}}}static class ChangeMaker extends Thread {@Overridepublic void run() {int threadValue = COUNTER;while (COUNTER < 5) {System.out.println("线程2 : " + (threadValue + 1) + "");COUNTER = ++threadValue;try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}}}}}

操作系统级别的缓存一致性解决方案

解决缓存不一致性问题,通常来说有以下2种解决方法:

  1. 通过在总线加LOCK#锁的方式
  2. 通过缓存一致性协议
    这2种方式都是硬件层面上提供的方式

总线加lock锁:
在早期的CPU当中,是通过在总线上加LOCK#锁的形式来解决缓存不一致的问题。因为CPU和其他部件进行通信都是通过总线来进行的,如果对总线加LOCK#锁的话,也就是说阻塞了其他CPU对其他部件访问(如内存),从而使得只能有一个CPU能使用这个变量的内存。
但是这种方式会有一个问题,由于在锁住总线期间,其他CPU无法访问内存,导致效率低下;

缓存一致性协议:
缓存一致性协议中,最出名的就是Intel 的MESI协议,MESI协议保证了每个缓存中使用的共享变量的副本是一致的。它核心的思想是:当CPU写数据时,如果发现操作的变量是共享变量,即在其他CPU中也存在该变量的副本,会发出信号通知其他CPU将该变量的缓存行置为无效状态,因此当其他CPU需要读取这个变量时,发现自己缓存中缓存该变量的缓存行是无效的,那么它就会从内存重新读取

在MESI协议中,每个cache line有4个状态,可用2个bit表示,它们分别是

状态 描述
M(Modified) 这行数据有效,数据被修改了,和内存中的数据不一致,数据只存在于本Cache中。
E(Exclusive) 这行数据有效,数据和内存中的数据一致,数据只存在于本Cache中。
S(Shared) 这行数据有效,数据和内存中的数据一致,数据存在于很多Cache中。
I(Invalid) 这行数据无效

多核cpu的缓存一致性相关推荐

  1. 多核CPU缓存一致性协议MESI

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

  2. 科普:CPU缓存一致性协议

    点击上方"朱小厮的博客",选择"设为星标" 后台回复"书",获取 CPU为何要有高速缓存 CPU在摩尔定律的指导下以每18个月翻一番的速度在 ...

  3. CPU缓存一致性协议MESI - 笔记

    CPU缓存一致性协议MESI CPU高速缓存(Cache Memory) CPU为何要有高速缓存 CPU在摩尔定律的指导下以每18个月翻一番的速度在发展,然而内存和硬盘的发展速度远远不及CPU.这就造 ...

  4. CPU 缓存一致性协议 MESI

    CPU 高速缓存(Cache Memory) CPU 为何要有高速缓存 CPU 在摩尔定律的指导下以每 18 个月翻一番的速度在发展,然而内存和硬盘的发展速度远远不及 CPU.这就造成了高性能能的内存 ...

  5. 4.什么是MESI缓存一致性协议?怎么解决并发的可见性问题?

    MESI一致性协议 小陈:老王,上一章你让我看看MESI一致性协议,我大概了解了一下. 老王:哦,来说说你对MESI一致性协议的理解 小陈:MESI协议也叫做缓存一致性协议,主要是用来进行协调多核CP ...

  6. 12 张图看懂 CPU 缓存一致性与 MESI 协议,真的一致吗?

    本文已收录到  GitHub · AndroidFamily,有 Android 进阶知识体系,欢迎 Star.技术和职场问题,请关注公众号 [彭旭锐] 进 Android 面试交流群. 前言 大家好 ...

  7. Java并发编程(六):从CPU缓存一致性协议到JMM(Java内存模型)

    注:本系列主要注重并发编程这块儿,JVM内容很多,会另外开专栏总结,此系列可能只是会稍微提及 一.跨平台和JVM 经过前面几篇博文的介绍,我们知道,任何编程语言编写的程序要想被计算机执行,都必须被翻译 ...

  8. 面试准备每日系列:计算机底层之并发编程(一)原子性、atomic、CAS、ABA、可见性、有序性、指令重排、volatile、内存屏障、缓存一致性、四核八线程

    文章目录 1. 什么是进程?什么是线程? 2. 线程切换 3. 四核八线程是什么意思 3.1 单核CPU设定多线程是否有意义 4. 并发编程的原子性 4.1 如何解决原子性问题 & atomi ...

  9. 10 张图打开 CPU 缓存一致性的大门

    前言 直接上,不多 BB 了. 正文 CPU Cache 的数据写入 随着时间的推移,CPU 和内存的访问性能相差越来越大,于是就在 CPU 内部嵌入了 CPU Cache(高速缓存),CPU Cac ...

最新文章

  1. 【MATLAB】交互式绘图(ginput,gtext,zoom)
  2. 模拟实现请求分页虚存页面替换算法_模拟卷二解答
  3. css3替代图片的尖角圆角效果
  4. TLSNotary中心化预言机(2) 核心功能
  5. Python字符串逐字符或逐词反转方法
  6. linux密码暴力破解之SHA-512破解
  7. python 操作redis,存取为字节格式,避免转码加
  8. 【HDU - 1599】find the mincost route (Floyd最小环,最短路问题)
  9. Tensorflow取消占用全部GPU
  10. Java中的ArrayList类和LinkedList
  11. spark: 二次排序-1
  12. Could not find artfact com.oracle:ojdbc7:jar:12.1.0.2.0 in nexus-aliyun
  13. 苹果4s怎么越狱_unc0ver 越狱工具来袭,免电脑操作,支持 A7-A12,支持iOS11~iOS12.4稳定越狱...
  14. tail -f 命令详解
  15. 复合函数高阶求导公式_复合函数求导公式大全 大学复合函数求导法则
  16. outlook分组邮件提醒
  17. python读txt文件-python读取文本文件数据
  18. Bugku web——秋名山老司机
  19. 【转载】站在牛顿墓前 文/张琦(北京大学)
  20. 鸿蒙系统支持手表,终于等到了!WATCH旗舰系列搭载鸿蒙系统,你会支持吗?

热门文章

  1. 局部加权回归Loess对比MFCC三角滤波(吴恩达机器学习中说,Loess算法用到了aircraft的自动驾驶中)
  2. 用python把微信好友头像拼成一张图
  3. 适合公司用的电子邮箱哪家好?企业邮箱最全功能介绍~
  4. 【机器学习】逻辑回归案例二:鸢尾花数据分类,决策边界绘制逐步代码讲解
  5. 单片机中常说的 1T 和 12T 的意思
  6. 论文阅读笔记: (2022.05, icra) Traffic Context Aware Data Augmentation for Rare Object Detection in Autonom
  7. 花青素近红外荧光染料Cyanine5 hydrazide,Cy5 hydrazide,1427705-31-4深蓝色粉末状
  8. dell笔记本指示灯闪烁_DELL笔记本电脑指示灯在电脑关闭后仍然闪烁是什么原因?...
  9. html调用摄像头直播,html5调用摄像头功能的实现代码
  10. 解决Ubuntu 安装时Unable to fetch some archives connection failed [ip: 91.189.91.39 80]