CPU读取数据顺序: L1–>L2–>L3–>内存–>外部存储器
MESI协议它规定每条缓存都有个状态为,同时定义了下面的四个状态
**修改态(modified)**该条数据是在CPU的缓存中,并且是被修改过的,与主内存里面的数据不一致,这条数据是要在某个的时间点回写到主内存当中,这个时间点是允许其他CPU读取主内相应的内存之前,当值被回写到主内存后缓存状态被修改为E.
**专有态(Exclusive)**该条数据是没有被修改过的,内容同于主内存,但不出现在其他Cache中,这条数据可以在任何时刻,其他CPU读取后状态修改为S,当CPU修改内容后状态就会变为M.
**共享态(shared)**这条数据内容同于主内存当也出现在其他CPU中(也就是可以被多个CPU进行缓存),当有一个CPU修改缓存时,其他CPU从该缓存行是可以被作废的,状态就会变为I.
**无效态(invalid)**这个缓存是无效的,可能是其他CPU修改了该缓存。
多处理器时,单个CPU对缓存中的数据进行了改动,需要通知给其他CPU,也就意味着CPU处理要控制自己的读写操作,还要监听其他CPU发出的通知,从而保证最终一致。
场景
当CPU写缓存时发现缓存区块正被其他CPU占用,为了提高CPU的处理性能,可能讲后面的读缓存命令优先执行。
as-if-serial
不管CPU怎么重排序,程序(单线程)的执行结果不能被改变。编译器、runtime和处理器都必须遵守as-if-serial,也就是说编译器和处理器不会在数据依赖关系操作重排序。
同样CPU在执行过程中会面临两个问题:
1. 高速缓存下,缓存中的数据于主数据并不是实时同步的,各CPU(或CPU核心)间缓存的数据也不是实时同步。在同一个时间点各个CPU看到的同一内存地址的数据可能不一致。
2. CPU执行指令重排序优化时,虽然遵守as-if-serial语义,但只能保证在单CPU自己执行的情况下保证结果正确。多核线程中,指令逻辑无法分辨因果关联。可能出现乱序,导致运行结果错误。
内存屏障
处理器提供了两个指令(Memory Barrier)用于解决上述问题