一个服务器中有多个核,每个核中有多个cpu,每个cpu有多个线程。缓存最少分为3级,1级为线程缓存,2级为核缓存,3级为多个核共享缓存。 产生缓存一致性问题:cpu主缓存count=0,此时线程A需要对count+1,线程B需要count+1,但是线程A读取count=0,修改了count+1还没来得及提交,线程B读取的还是count=0,然后线程A,线程B都提交到cpu主缓存,此时count=1,产生错误,应该count=2 解决方式: 1.cpu主缓存加锁,产生问题效率变低,因为线程A使用count时,其他cpu线程都在等待 2.缓存一致性协议mesi:对单个缓存行进行加锁,不会影响cpu的其他线程
mesi协议:为了解决cpu缓存一致性问题 mesi协议的4种状态:m e s i MESI是Midified(已修改),Exclusive(独占),Shared(共享),Invalidated(已失效)的缩写,对应Cache Line的四种状态。 多核CPU的cache和内存的构成可以简化为:每个CPU有自己的独有的cache,然后大家共享内存,当每个CPU从cache中读取数据时,如何保证所有cache和内存中数据的一致性,即使MESI协议要解决的问题。
状态解释:
【M已修改】: 即脏标记,表示当前cache line中的数据已经被修改,没有被写到内存中。 【i已失效】: 状态,表示这个cache line里的数据已经失效,是不可以读取的数据。 【E独占】和【S共享】:状态都表示这个cache line中的数据是干净的(即与内存中的数据是一致的,共享同时也表示与其他cpu cache中的数据是一致的)。
状态转换:
E独占:数据只在被一个cpu读取。 S共享:独占状态基础上,又有其他cpu读取这份数据到自己的缓存行。代表同一份数据在多个cpu的缓存行中 i已失效:当共享状态时,代表同一份数据在多个cpu的缓存行中,不能直接修改,而是要先向所有的其他 CPU 核心广播一个请求,要求先把其他核心的 Cache 中对应的 Cache Line 标记为【已失效】状态,然后再更新当前Cache 里面的数据(这时数据的状态就变为独占的)
https://www.scss.tcd.ie/Jeremy.Jones/VivioJS/caches/MESIHelp.htm