ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

并发编程之MESI缓存一致性协议

2022-01-10 22:32:21  阅读:206  来源: 互联网

标签:协议 缓存 Cache MESI 一致性 line CPU 编程


MESI缓存一致性协议,用于解决多线程环境下的缓存一致性问题。

缓存一致性问题

在多处理器系统中,每个处理器都有自己的高速缓存,而它们又共享同一主内存。当多个处理器的运算任务都涉及同一块主内存区域时,将可能导致各自的缓存数据不一致的情况,如果真的发生这种情况,那同步回主内存时以谁的缓存数据为准呢?!这个就是缓存一致性问题。

为了解决一致性的问题,需要各个处理器访问缓存时都遵循一些协议,在读写时要根据协议来进行操作。主要使用的协议是:MESI缓存一致性协议

早期的计算机使用的是【总线加锁】的方式,但是这种方式性能太低,现在使用的基本都是【缓存一致性协议】,但是总线加锁也是有的,某些情况下会用总线加锁方式。

原子性 可见性 有序性

原子性,可见性,有序性是并发编程中三个重要的概念。

  • 可见性:指的是当一个线程修改了某个共享变量的值,其他线程是否能够马上得知这个修改的值。
  • 有序性:指的是对于单线程的执行代码,我们总是认为代码的执行是按顺序依次执行的(程序编译成机器码指令后可能会出现指令重排现象,重排后的指令与原指令的顺序未必一致)。
  • 原子性:指的是一个操作是不可中断的,即使是在多线程环境下,一个操作一旦开始就不会被其他线程影响。

缓存一致性协议不是万能的,它只是解决了可见性问题而已,没法解决有序性和原子性问题。

缓存行(Cache line)

了解缓存一致性协议之前,先了解下缓存行(Cache line)。

CPU缓存(cache)是由很多个Cache line组成的。Cache line是CPU缓存和主存交换数据的最小单位,Cache line大小是固定的,通常为64Byte。

当数据大小超过Cache line的固定大小时,就没法用缓存一致性协议了,会转而使用总线加锁。

当从内存中取数据到cache中时,会一次取一个Cache line大小的内存区域到cache中,然后存进相应的Cache line中。

MESI缓存一致性协议

作用:解决多线程环境下的缓存一致性问题。

MESI是4种状态的首字母:Modified、Exclusive、Shared、Invalid。

状态描述监听任务

M 修改(Modified)

该Cache line有效,数据被修改了,和内存中的数据不一致,数据只存在于本Cache中。缓存行必须时刻监听所有试图读该缓存行相对就主存的操作,这种操作必须在缓存将该缓存行写回主存并将状态变成S(共享)状态之前被延迟执行。

E 独享、互斥(Exclusive)

该Cache line有效,数据和内存中的数据一致,数据只存在于本Cache中。缓存行也必须监听其它缓存读主存中该缓存行的操作,一旦有这种操作,该缓存行需要变成S(共享)状态。

S 共享

(Shared)

该Cache line有效,数据和内存中的数据一致,数据存在于很多Cache中。缓存行也必须监听其它缓存使该缓存行无效或者独享该缓存行的请求,并将本缓存行变成 I(无效)状态。

I 无效

(Invalid)

该Cache line无效

工作原理

  1. 变量X=1读到CPU1的缓存中,标记为独占状态(E),此CPU会监听(总线嗅探机制)其他CPU对这块内存的操作
  2. CPU2也从内存中讲X=1读到缓存中,这个时候CPU1通过总线嗅探机制会知道这个操作,这时会把X的状态改成共享状态(S),当然,CPU2中X也是共享状态
  3. CPU1中把X改成2,准备回写到主存中,CPU1中会锁住这个缓存行,然后把X状态改成修改状态(M),然后往总线发一个消息
  4. 其他CPU此时嗅探到这个消息,如果此CPU上也有X的缓存的话,会修改为无效状态(I)
  5. CPU1成功将X=2回写到主存后,会把X修改为独占状态(E)
  6. 其他CPU此时需要再访问X的话,发现是无效状态,则需要从主从中重新去读取

如果两个CPU同一时间要去修改X会怎样?

一个指令周期内会进行裁决,只能有一个修改成功!

如果裁决失败,整个缓存行(Cache line)会整体失效。

缓存一致性协议什么时候触发

那么又有一个很重要的问题,缓存一致性协议什么时候触发呢?

首先,缓存一致性协议需要硬件的支持,但是这个问题不用考虑,因为现在的硬件已经是支持的。只不过该协议是弱一致,正常情况下,系统操作并不会进行缓存一致性(MESI)的校验。

要触发缓存一致性协议,需要在汇编指令中添加 #Lock信号

但是我们平时编程中,显然不可能去手动写什么 #Lock信号。对于java来说,就是volatile关键字,因为volatile关键字可以触发#Lock信号,从而能触发缓存一致性协议。当然,volatile关键字还不止这一个功能,它还可以一定程度上禁止指令重排序!也就是说,volatile关键字可以同时解决可见性问题以及有序性问题,不过不能解决原子性问题!

什么时候缓存一致性协议会失效

  1. 如果X存储长度超过一个缓存行,会使用总线加锁。不能一个数据横跨多个缓存行(数据可以横跨多个缓存行,只是缓存一致性协议会失效)
  2. CPU并不支持缓存一致性协议。当然,这肯定是早期的CPU

标签:协议,缓存,Cache,MESI,一致性,line,CPU,编程
来源: https://blog.csdn.net/xujingyiss/article/details/122173201

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有