内存缓冲和无效队列

存储缓冲区和无效队列还是为了更好的利用CPU的高执行率。

首先印出来一个概念:缓存行(cacheline),数据在缓存里面不是杂乱无章的存储的,它是以缓存行的形式存储的。缓存行的大小就是CPU一次处理的最大数据的大小。CPU读取和修改数据都是直接对缓存行进行操作的,高速缓存里面都是有一个个的缓存行组成的。
在此特别感谢http://www.wowotech.net/kernel_synchronization/memory-barrier.html 这篇文章的作者,里面写的非常细。

1.MESI协议的缺点

关于MESI协议我之前的一篇文章https://blog.csdn.net/qq_30055391/article/details/84862422 介绍过。
在MESI协议里面如何一个CPU要修改一个处于shared状态的变量非常麻烦的。首先、
1.本地缓存行将会通过寄存器控制器向远程拥有相同缓存行的寄存器发送一个RFO请求(Request For Owner),告诉其他CPU里面的缓存把缓存里面的值为valid状态,然后待收到各个缓存的(valid ack)已经完成无效状态修改的回应之后,
2.再把自己的状态改为Exclusive,之后再进行修改。
3.修改后再改为Modified状态,数据写入缓存行。
上面这几步大家可以看到第一步的时候,CPU需要在等待所有的valid ack之后才会进行下面的操作。这部分就会让CPU产生一定的阻塞,无法充分利用CPU。这个时候就印出来了存储缓冲区 storeBuffer。

2.存储缓冲区

存储缓冲区的作用就是修改一个变量的时候,直接执行修改的操作不直接镇对缓存行,而是针对一个叫制作storeBuffer的位置来操作的。这样CPU在执行修改操作的时候,直接把数据写入到storeBuffer里面,并发出广播告知其他CPU,你们的缓存里面需要变为validate状态,然后去执行其他的操作,等接受到validate ack的时候才会回来把缓冲区里面的值写入到缓存行里面。
下面是一个简单的架构图。
在这里插入图片描述

3.无效队列

存储缓冲器的大小是有限的。如果存储缓冲区满了,那么依然需要等待validate ack的回复后才可以继续执行运算。但是对方的CPU可能当时正在执行其他的操作。无法及时把缓存里面的值改为validate状态,并发回validate ack操作。这个时候为了继续优化这段CPU空闲的时间。就出现了无效队列!
在这里插入图片描述
无效队列的作用就是CPU接收到validate广播的时候马上返回给对方validate ack响应。等当前的操作执行完再回来真正的把缓存里面的值标识为validate状态。

4.存储缓存跟无效队列造成的问题

存储缓存造成的问题就是在对方CPU还没有给我们回答的时候我们已经执行下一步代码了。
无效队列造成的问题就是在CPU已经给对方应答的时候自己本身还没有去把这个值validate掉。
上面的这两种情况有的时候我们是不希望它发生的。这个时候我们上一篇文章讲到的内存屏障就派上用场了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值