线程同步,和cache一致性的疑惑
看了这篇文章中
http://images.cnblogs.com/cnblogs_com/1-2-3/thread-synchronization/7.png
的情况
源码在这里
class Program
{
static int n = 0;
static void foo1()
{
for (int i = 0; i < 1000000000; i++) // 10 亿
{
n = n + 1;
}
Console.WriteLine("foo1() complete n = {0}", n);
}
static void foo2()
{
for (int j = 0; j < 1000000000; j++) // 10 亿
{
n = n + 1;
}
Console.WriteLine("foo2() complete n = {0}", n);
}
static void Main(string[] args)
{
new Thread(foo1).Start();
new Thread(foo2).Start();
}
}
作者说 n在两个CPU的cache中都分别在加一,所以 进行了3个循环后 很可能 两边的cache里面 n都是3
我自己加了代码,发现他说的情况是有的。
但是按照intel的MESI缓存一致性协议的话 这种情况不应该发生啊:
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状态。
到底为什么这个缓存一致性协议 形同虚设呢?