罪魁祸首_可见性问题

计算机的可见性问题,称得上是历史遗留问题了, 当初硬件工程师们想尽办法
但是却在性能与可见性之间. 选择了性能.....
似乎鱼与熊掌之间就真的不可兼得

那么可见性问题就交由我们软件工程师来搞定了…

可见性问题的由来:

众所周知,在电脑中存储数据,运算数据的核心设备 有 IO设备, 内存, CPU 其中一个比一个块, 内存甩IO 几条街, CPU 甩内存几条街.

绝大部分程序都需要三者配合, 正如水桶定理,一个水桶能装多少水取决于最短的那块木板

按道理说最慢的是 IO设备,但是 由于内存的引入, 提前将IO中常用的数据读入内存中以加速程序的运行,这点已经屡见不鲜了,

所以硬件工程师们绞尽脑汁,得出了改进方式,那就是在CPU 与 内存之间 新加入一层 高速缓存. (当然改进不止这么一块,但是我们先集中这一块)

那么什么是高速缓存?

  1. 介于CPU 与内存之间
  2. 辅助内存,合理的范围内尽最大限度利用CPU资源

高速缓存的分类 :

高速缓存也分L1 ,L2 ,L3,等 如图:
在这里插入图片描述
其中L1 与L2 是直接在CPU之中的,属于CPU私有缓存. 但是 L3缓存 是多个CPU核心之间共享的

L1速度最快
但是也缓存大小也最难扩大只有 128kb

二级缓存比一级要慢,但是
缓存大小比一级要大 有 521kb

以此类推,越往后的缓存添加越是容易,空间大小也越发庞大,但是没有太大的意义,因为速度已经慢下去了,还不如加内存条呢

此时CPU的工作流程(串行):

  1. 内存把数据写入高速缓存

  2. CPU 读入高速缓存

  3. CPU 运算数据,把结果写入高速缓存

  4. 从高速缓存中将数据同步至主内存

  5. 其他的CPU核心 从主内存中读取最新的数据放入高速缓存中

看起来似乎一切都很完美…


但是此时问题就出现了 在多核CPU 情况下各有各自的高速缓存,

  1. CPU_A 把变量 i=0 copy 到私有缓存中

  2. CPU_B把也变量 i=0 copy 到私有缓存中.

  3. 那么此时CPU_A修改了变量 i=1

  4. CPU_B 是完全不知情了,那么程序就出错了

怎么办? 硬件工程师们抓狂了…

工程师A: 能不能让 CPU_A 在把 i 变成 1之后 告诉其他 CPU 一声?

工程师B: 似乎可行......

经过一番激烈的唇枪舌战, 如何让CPU通知其他CPU , 每个标志什么意思,… 等标准出现了 这就是 “缓存一致性协议”.

由于 “缓存一致性协议” 只是一个理念 ,每个厂家基于此概念实现出来的产品也是不同的 其中 MESI 算是是市面上热门的一种实现方式

MESI分别有:

  1. S(Shared): 共享状态
    代表当前数据可能
    已经被各个CPU内存缓存了,
    并且各个缓存行的数据与主内存保持一致

  2. I(Invalid):失效状态:
    当其他CPU高速缓存中的值被修改之后,
    当前CPU还是原来的值,那么就会是此状态

  3. M(Modified)修改状态:
    代表当前的 CPU_A 修改了 CPU_A的高速缓存
    中的某行数据,导致当前的值与主内存中不一致
    ps:
    此时其他CPU高速缓存中,当前数据就会变成
    Invalid

  4. E(Exclusive):独占状态:
    代表除了当前CPU 的高速缓存之中有 缓存当前
    数据之外,其他CPU的高速缓存中并没有缓存当前数据
    且当前CPU的高速缓存中的值 与主内存中的值是一致的

至此,CPU之间已经可以互相通讯了,

当CPU_A 中的值被修改的时候 CPU_B 也就知道了, 从而将 CPU_B 私有高速缓存中的 变量变成 Invalid然后再去主内存中取出最新的值 .

但是如果你认为可见性问题就此被消灭,那就太天真了

to young to simple …you

为什么呢? 因为 . 因为CPU之间的通讯本来是同步,

当CPU_A通知其他 CPU的时候 ,需要等到其他CPU的回执此时CPU_A在等待其他CPU回执的时候是阻塞状态的

这时当年有 性能狂魔潜质的工程师们忍受不住了,加入了一层中间键 storeBuffer ,自此将CPU之间的通讯变成了异步方式,

众所周知,只要是异步的, 那么后面 发送的消息就有可能在前面的消息之前到达目标
例如:

  1. CPU_A发出了信息A
  2. CPU_A发出了信息B
  3. 信息B跑的飞快,已经快要追上信息A了
  4. 什么 信息B超过信息A了 ! ! ! ! 弯道超车! ! !
  5. 信息B跑的很快,但是信息A紧随其后. 终点就在前方.
  6. 冲线了! 信息B率先抵达终点.

不得不说当年的工程师们做得一手好似… 但是没有他们如今的计算机也不会有如今的发展速度.

至此当年的工程师们,一致放弃了从硬件上 一劳永逸的解决这个问题的想法,转而留下了解决方式 那就是在需要的时候通讯操作变成同步的, 且后面涉及 此操作将是同步的 这个方式被称之为 “内存屏障”

内存屏障由我们软件工程师,在编写软件程序的时候手动调用,至此才算是给可见性这个问题一个解决方案

发布了41 篇原创文章 · 获赞 225 · 访问量 8723

猜你喜欢

转载自blog.csdn.net/weixin_43843042/article/details/104697554
今日推荐