在并发编程中,缓存一致性协议(MESI)缓存行的四种状态达到缓存数据的一致,会带来CPU层面的阻塞,这时可以引入storebuffer让CPU将数据写入storebuffer中,让CPU误以为数据已经同步了来防止CPU层面的阻塞。
{主内存:i=0
CPU0:cache0 i=1(可能会变成独占状态Exclusive,修改状态Modify)
CPU1: cache1 i=0(变成失效状态invalid)}
-写入缓存时必须处于ME状态,或者使得其他cpu缓存处于失效状态,失效后把数据同步到主内存-
提升CPU利用效率:首先数据是S状态,在CPU写入数据时,变为I状态,之后再把数据写入到storebuffer中,写入之后会storebuffer会发送invalidate消息使得其他缓存了该缓存行的CPU失效这是一个异步化的过程
异步化会出现可见性问题:当storebuffer中写入数据时,需要得到其他其他CPU的通知才能把数据同步到缓存行在同步到主内存中,若没有同步到主内存中也会发生可见性问题。
CPU的异步执行会导致乱序执行的问题,CPU的异步执行->重排序->可见性问题
可见性问题:
当storebuffer中的数据没有同步到主内存中,处于Modify修改状态,其他CPU无法加载,就会导致CPU的缓存数据不一致
1、修改(Modify)
高速缓存行仅存在于当前高速缓存中,并且是脏的 - 它已从主存储器中的值修改(M状态)。
描述: 当CPU接收到来自storebuffer的失效通知时,会返回ACK值使得需要写数据的CPU变成Modify状态。
{主内存:i=0 CPU0:cache0 i=1, storebuffer i=1 CPU1:cache1 i=0}
2、独占(Exclusive)
缓存行仅存在于当前缓存中,但是干净 - 它与主内存匹配。
描述: 该Cache line有效,数据和内存中的数据一致,数据只存在于本Cache中。
{主内存:i=1 CPU0:cache0 i=1, CPU1:cache1 i=0}
3、共享(Share)
表示此高速缓存行可能存储在计算机的其他高速缓存中并且是干净的 - 它与主存储器匹配。
描述: 数据可能已经被多个CPU缓存了,各个缓存行的数据和组内存的数据保持一致。
{主内存:i=0 CPU0:cache0 i=0, CPU1:cache1 i=0}
4、无效(invalid)
表示此缓存行无效(未使用)。
描述: 在storebuffer写入数据以后会告知Invalid消息使得其他缓存了该缓存行的CPU失效。
{主内存:i=0 CPU0:cache0 i=1, storebuffer i=1, CPU1:cache1 i=0}
CPU提供了内存屏障指令:可以在适当的地方加入内存屏障指令,使得CPU直接与主内存进行交互。解决可见性问题。
内存屏障: 写屏障、读屏障、全屏障
写屏障(store barrier):告知处理器在写屏障之前存储在storebuffer的指令同步到主内存中
读屏障(load barrier):(失效队列):处理器在加了读屏障之后的操作保证能够读取到最新的数据
全屏障(full barrier):读屏障和写屏障配合使用,为了解决可见性