CAS指令与MESI缓存一致性协议

转: 

CAS(Compare-And-Swap)指令是并行程序设计最基础的基石,随着愈来愈多的本本都用上了双核,这个世界已经快速步入并行计算时代,CAS指令发挥的做用也就愈来愈大。CAS指令,在Intel CPU上称为CMPXCHG,的做用是将指定内存地址的内容与所给的某个值相比,若是相等,则将其内容替换为所给的另外一个值,这一系列操做是原子的,不可能被中断。基本上全部的同步机制,与信号量、Java中的synchronized等的实现最终都要用到CAS指令,即便锁无关的数据结构也离不开CAS指令。  关于CAS指令最著名的传闻是CAS须要锁总线,所以CAS指令不但慢并且会严重影响系统并发度,即便没有冲突是也同样。不过在较新的CPU中(对于Intel CPU来讲是486以后),事实并不是如此。目前的CPU通常都采用了很好的缓存一致性协议,在不少状况下可以防止锁总线的发生,这其中最著名的就是Intel CPU中使用的MESI缓存一致性协议。  先来讲说缓存一致性问题。为了提升数据访问效率,每一个CPU上都有一个容量很小(如今通常是1M这个数量级),速度很快的缓存,用于缓存最常访问的那些数据。因为操做内存的速度实在太慢,数据被修改时也只更新缓存,并不直接写出到内存中去,这一来就形成了缓存中的数据与内存不一致。若是系统中只有一个CPU,全部线程看到的都是缓存中的最新数据,固然没问题。但若是系统中有多个CPU,同一分内存可能会被缓存到多个CPU中,若是在不一样CPU中运行的不一样线程看到同一分内存的缓存值不同就麻烦了,所以有必要维护这多种缓存的一致性。固然要作到这一点只要一有修改操做,就通知全部CPU更新缓存,或者放弃缓存下次访问的时候再从新从内存中读取。但这会Stupid的实现显然不会有好的性能,为解决这一问题,产生了不少维护缓存一致性的协议,MESI就是其中一种。  MESI协议的名称由来是指这一协议为缓存的每一个数据单位(称为cache line,在Intel CPU上通常是64字节)维护两个状态位,使得每一个数据单位可能处于M、E、S或I这四种状态之一。各类状态含义以下:  M: 被修改的。处于这一状态的数据只在本CPU中有缓存,且其数据已被修改,没有更新到内存中  E: 独占的。处于这一状态的数据只在本CPU中有缓存,且其数据没有被修改,与内存一致  S: 共享的。处于这一状态的数据在多个CPU中有缓存  I: 无效的。本CPU中的这份缓存已经无效了。  当CPU要读取数据时,只要缓存的状态不是I均可以从缓存中读,不然就要从主存中读。这一读操做可能会被某个处于M或E状态的CPU截获,该CPU将修改的数据写出到内存,并将本身设为S状态后这一读操做才继续进行。只有缓存状态是E或M时,CPU才能够修改其中的数据,修改后缓存即处于M状态。若是CPU要修改数据时发现其缓存不处于E或M状态,则须要发出特殊的RFO指令(Read For Ownership),将其它CPU的缓存设为I状态。  所以,若是一个变量在某段时间内只被一个线程频繁修改,则对应的缓存早就处于M状态,这时CAS操做就不会涉及到总线操做。因此频繁的加锁并不必定会影响系统并发度,关键是看锁冲突的状况严重不严重,若是常常出现冲突,即缓存一会被这个CPU独占,一会被那个CPU独占,这时才会不断产生RFO,影响到并发性能。

相关文章
相关标签/搜索