拜读了Richter先生关于内存一致性问题的论文,分析的很透彻,这里做一下自己的小结。
示例代码:
1
internal sealed class CacheCoherencyProblem
2
{
3
private Byte m_initialized = 0;
4
private Int32 m_value = 0;
5
6
public void Thread1()
7
{
8
m_value = 5;
9
m_initialized = 1;
10
}
11
12
public void Thread2()
13
{
14
if (m_initialized == 1)
15
{
16
Console.Write(m_value);
17
}
18
}
19
}
internal sealed class CacheCoherencyProblem2
{3
private Byte m_initialized = 0;4
private Int32 m_value = 0;5

6
public void Thread1()7
{8
m_value = 5;9
m_initialized = 1;10
}11

12
public void Thread2()13
{14
if (m_initialized == 1)15
{16
Console.Write(m_value);17
}18
}19
}在多CPU或多内核CPU机器中,因CPU高速缓存机制,而产生内存不一致现象
假设在一个多CPU的机器上创建了该实例:
CPU1执行Thread1方法,CPU2执行Thread2方法,假定程序的执行顺序为:
1.CPU2的线程在读取某个字节时,m_value字段的字节刚好位于这个字节之前,
根据CPU高速缓存机制,m_value被预读到CPU高速缓存中(因为应用程序通常
读取的字节在内存中彼此互邻,这样可以提升性能)
2.CPU1执行Thread1,将m_value改为5,但根据CPU高速缓存机制,改变仅暂时
存在于CPU1的高速缓存中,直到某个时间才会刷新到内存中。我们这里假设
此步操作可能需要经过很久才会反映到内存中
3.CPU1继续执行Thread1方法,同样在自己的高速缓存中,修改了m_initialized
的值为1。但这次的m_initialized却处在CPU1高速缓存的不同区段,结果
是很快被刷新到内存中了。
4.CPU2开始执行Thread2方法,当访问m_initialized值时,CPU2会因高速缓存中
不存在m_initialized而去读取内存,结果是CPU2读取到m_initialized=1,随即
进入了if语句块。
5.CPU2继续执行Thread2方法,此时CPU2同样也会因高速缓存中不存在m_value而
去内存中取值,但因为CPU1还没有将自己的m_value=5更新到内存,所以CPU2取到
了m_value=0


浙公网安备 33010602011771号