线程同步,和cache一致性的疑惑

xeon_pan 2009-10-21 05:12:44
看了这篇文章中

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状态。


到底为什么这个缓存一致性协议 形同虚设呢?
...全文
252 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
xeon_pan 2009-11-02
  • 打赏
  • 举报
回复
看著玩的,只是好奇想學 呵呵
xeon_pan 2009-10-23
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 fanbin23 的回复:]
I like this question:) 我来补充一下1楼说的:

这个和CPU Cache没有关系,就算不用Cache,这个程序一样会出问题。一致性协议是使得多个CPU issue出来的load/store操作能够以一个约定的“序”对内存可见,Cache一致性协议是在Cache存在的情况下对这个“序”的一个约定和实现。常见的MESI协议简单说就是按照load/store出现在总线上的“序”对内存可见的。(好久没看书了,不保证说的准确)。

但是,load/store issue到总线的次序就不归一致性协议管了。这个例子中n=n+1在RISC机器一般会生成:

ld n, reg
add reg, 1
st reg, n

由于这三条指令并没有被锁保护,所以他们的执行并不是原子的,而是可以interleave的。这才是造成问题的根本原因。
[/Quote]

请问这些知识,要看哪方面的书呢?谢谢
fanbin23 2009-10-23
  • 打赏
  • 举报
回复
如果你知道MESI,应该知道看什么书啊。

http://product.dangdang.com/product.aspx?product_id=693715
这本不错,现在可能不好买了。或者搜论文看,memory consistency有一篇综述。不过除非你需要设计一个线程模型,否则基本用不着。

[Quote=引用 8 楼 xeon_pan 的回复:]
引用 4 楼 fanbin23 的回复:
I like this question:) 我来补充一下1楼说的:

这个和CPU Cache没有关系,就算不用Cache,这个程序一样会出问题。一致性协议是使得多个CPU issue出来的load/store操作能够以一个约定的“序”对内存可见,Cache一致性协议是在Cache存在的情况下对这个“序”的一个约定和实现。常见的MESI协议简单说就是按照load/store出现在总线上的“序”对内存可见的。(好久没看书了,不保证说的准确)。

但是,load/store issue到总线的次序就不归一致性协议管了。这个例子中n=n+1在RISC机器一般会生成:

ld n, reg
add reg, 1
st reg, n

由于这三条指令并没有被锁保护,所以他们的执行并不是原子的,而是可以interleave的。这才是造成问题的根本原因。


请问这些知识,要看哪方面的书呢?谢谢
[/Quote]
lzhdim 2009-10-23
  • 打赏
  • 举报
回复
操作系统的书吧。还有就是Intel相关开发的书。比如多核程序设计之类。。。
problc 2009-10-22
  • 打赏
  • 举报
回复
up
sdfdl 2009-10-22
  • 打赏
  • 举报
回复
帮up
fanbin23 2009-10-21
  • 打赏
  • 举报
回复
I like this question:) 我来补充一下1楼说的:

这个和CPU Cache没有关系,就算不用Cache,这个程序一样会出问题。一致性协议是使得多个CPU issue出来的load/store操作能够以一个约定的“序”对内存可见,Cache一致性协议是在Cache存在的情况下对这个“序”的一个约定和实现。常见的MESI协议简单说就是按照load/store出现在总线上的“序”对内存可见的。(好久没看书了,不保证说的准确)。

但是,load/store issue到总线的次序就不归一致性协议管了。这个例子中n=n+1在RISC机器一般会生成:

ld n, reg
add reg, 1
st reg, n

由于这三条指令并没有被锁保护,所以他们的执行并不是原子的,而是可以interleave的。这才是造成问题的根本原因。
gisyellow 2009-10-21
  • 打赏
  • 举报
回复
高深,学习。。
zcandyly20211 2009-10-21
  • 打赏
  • 举报
回复
友情up!
guoyichao 2009-10-21
  • 打赏
  • 举报
回复
这个和CPU Cache没有关系,你既然学习过intel的cpu cache知识那就应该明白cpu是怎么进行加法计算的,如果还不明白就仔细看下cpu在进行加法计算的时候是怎么运作的。

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧