volatile如何保证可见性:MESI缓存一致性

CPU为何要有高速缓存
CPU在摩尔定律的指导下以每18个月翻一番的速度在发展,然而内存和硬盘的发展速度远远不及CPU。这就造成了高性能能的内存和硬盘价格及其昂贵。然而CPU的高度运算需要高速的数据。为了解决这个问题,CPU厂商在CPU中内置了少量的高速缓存以解决I\O速度和CPU运算速度之间的不匹配问题。
在CPU访问存储设备时,无论是存取数据抑或存取指令,都趋于聚集在一片连续的区域中,这就被称为局部性原理。
时间局部性(Temporal Locality):如果一个信息项正在被访问,那么在近期它很可能还会被再次访问。比如循环、递归、方法的反复调用等。
空间局部性(Spatial Locality):如果一个存储器的位置被引用,那么将来他附近的位置也会被引用。比如顺序执行的代码、连续创建的两个对象、数组等。
带有高速缓存的CPU执行计算的流程:
1. 程序以及数据被加载到主内存
2. 指令和数据被加载到CPU的高速缓存
3. CPU执行指令,把结果写到高速缓存
4. 高速缓存中的数据写回主内存

volatile如何保证可见性?

用volatile去修饰变量 那么在汇编层面在变量前面加一个lock前缀 而lock前缀又会触发缓存一致性协议 通过缓存一致性协议可以保持即使多个线程在操作是也能保证可见性

 

多核CPU多级缓存一致性协议MESI

MESI协议缓存状态

 多核读取
CPU A发出了一条指令,从主内存中读取x。
CPU A从主内存通过bus读取到 cache a中并将该cache line 设置为E状态。
CPU B发出了一条指令,从主内存中读取x。
CPU B试图从主内存中读取x时,CPU A检测到了地址冲突。这时CPU A对相关数据做出响应。此时x 存储于cache a和cache b中,x在chche a和cache b中都被设置为S状态(共享)。

修改数据
CPU A 计算完成后发指令需要修改x.
CPU A 将x设置为M状态(修改)并通知缓存了x的CPU B, CPU B将本地cache b中的x设置为I状态(无效)CPU A 对x进行赋值。

 同步数据
CPU B 发出了要读取x的指令。
CPU B 通知CPU A,CPU A将修改后的数据同步到主内存时cache a 修改为E(独享)
CPU A同步CPU B的x,将cache a和同步后cache b中的x设置为S状态(共享)。

 

 总结:MESI 缓存一致性

当A线程去读取主内存里面的数据时 如果发现这个变量被lock前缀修饰了 那么就会被cpu监听到 那么在A这边就会有一个副本变量 此时就会给副本变量标识上E(独占)状态

如果此时B线程也来读这个变量 也会被cpu监听到 此时A线程的副本变量会变成S(共享)状态 B线程副本变量也会变成S状态  变量变成了共享状态就不可随意修改 因为其他线程也有 需要维护一致性

而对于多个线程拥有共享变量 他们会去争抢一把锁 谁先抢到锁(锁缓存行)谁就去修改 就会将持有锁线程变量由S(共享)状态改为M(已修改)状态  由于缓存行是各个线程独有的 互不影响 所以当加完锁后的线程就会发送一个消息进行广播 就会被拥有同样副本变量的线程捕捉到 其他线程此时就会把自己的副本变量改为I(失效)状态 然后其他线程通知 A, A将修改后的数据同步到主内存时cache a 修改为E(独享)   如果是两个线程同时去加锁 那么就由bus总线去裁判谁生效

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值