并发编程-缓存一致性协议

并发编程-缓存一致性协议

1.首先需要了解现代计算机的硬件基本结构,如下图所示
现代计算机的硬件基本结构
在上述图中,CPU中包括程序计数器(PC),寄存器文件,算法/逻辑单元(ALU),CPU缓存(L1,L2,L3),总线接口,读写速度由快到慢排序为:寄存器>L1>L2>L3。
2.了解了现代计算机的硬件基本结构之后,我们模拟两个CPU都在操作主内存的x变量,假如主内存有一个x=5的变量,现在需要进行x=x+1的计算在不考虑缓存一致性的前提下,每个CPU操作x的步骤如下:
1.在CPU的寄存器中查找是否存储了变量x的地址,如果有,则对x进行+1的操作,如果没有,则进行步骤2;
2.从CPU的L1缓存中查找x的地址是否存在,存在则将L1中x的地址传输给CPU 寄存器进行计算,如果不存在,,则执行步骤3
3.从L2中查找x的地址,如果存在,则将x的地址传输到L1,再由L1传输到CPU的寄存器,进行计算;如果不存在,则执行步骤4
4.从L3中查找x的地址,如果存在,则将x的地址由L3->L2->L1->CPU寄存器的路线传输到CPU寄存器,由CPU寄存器进行计算,如果不存在,则从主内存中获取x的地址传递到L3,再由L3->L2->L1->CPU寄存器的路线传输到CPU寄存器,进行计算。
上述操作会出现以下问题
如果存在两个CPU对变量x进行+1的操作,当同时把各自修改的值写入主内存时,会出现值被覆盖的现在,本应该进行了两次+1的操作,x=7,结果有一次+1被覆盖,导致x=6。
解决上述问题的方法有两种:
1.总线加锁
当CPU1对x(主内存)进行读写操作时,会对总线进行加锁,此时CPU2就不能对x(主内存)进行读写操作,这种方法已经很少用了,一般都是用第2种方式:缓存一致性协议。
2.缓存一致性协议(mesi)
首先我们得清楚,CPU缓存的最小存储单元是缓存行(32字节/64字节/128字节)
机械硬盘的最小存储单元:簇
缓存一致性协议的含义如下图所示
缓存一致性协议
Mesi协议运行的步骤如下:
前提:CPU1和CPU2对应的是java的两个不同的方法在操作同一个变量x,x被volatile关键字修饰。
1.首先CPU1将x读取到CPU1的缓存中,并将x修改为E状态,因为x被volatile修饰,因此在读取x时,会在改操作对应的汇编指令前加一个#lock的锁,从而触发缓存一致性协议,总线会时刻监听x的状态变化(总线嗅探机制)
步骤1
2.当CPU2(更多CPU也一样)读取主内存的x时,CPU1和CPU2的缓存中的x会变成S(共享状态)
步骤2
3.此时CPU1要将缓存中的x变量的值回写到主内存,此时需要给存储x的缓存行加锁,即将CPU1要将缓存中的x变量的状态设置为M,此时总线嗅探到CPU1缓存中x的状态为M,即告知其他CPU,CPU1缓存中x的状态为M,此时将其他CPU的CPU缓存中的x的状态设置为I(无效),然后将CPU1中缓存的x=6的值写回主内存;
步骤3
4.写回主内存之后,再将CPU1缓存中x的状态修改为E,当CPU2还需要对x进行操作,需要将x=5(I)的值丢弃,从新从读取主内存中的x值,将会继续从步骤2开始进行后续流程。
步骤4
注:
1)如果两个CPU同一时间去修改x(M),解决办法为:一个指令周期内,会进行裁决,随机选择一个CPU进行x的修改操作,另外一个CPU的x的值则设置为I(无效),那么无效的那个CPU缓存会立刻去主内存获取x的新的值吗,不一定,取决于你的代码是否需要再次去获取主内存中x的值。
2)什么情况下缓存一致性协议会失效(mesi)?
①缓存行失效:如果x的存储长度大于一个缓存行,x横跨两个缓存行,此时不能对缓存行加锁,此时会加总线锁
②CPU并不支持缓存一致性协议(奔腾系列cpu)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值