内存一致性

示例代码:

 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}

在多CPU或多内核CPU机器中,因CPU高速缓存机制,而产生内存不一致现象
假设在一个多CPU的机器上创建了该实例:
CPU1执行Thread1方法,CPU2执行Thread2方法,假定程序的执行顺序为:
1.CPU1的线程在读取某个字节时,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



内存一致性

write back会涉及内存一致性,涉有到一系列的问题:

1)多处理要系统更新cache时,一个处理器修改了cache的内容,第二个处理器将不能访问这个cache,直到这个cache的内容被写内存.
在现代处理器中硬件已经做了精心的设计,确保这种事情不会发生,硬件负责保持cache在各个CPU之间一致.

2)外围硬件设备可以通过DMA(Direct Memory Access)访问内存,而不让处理器知道,也不会利用cache,这样在内存和cache之间就会出现不同步的情况.
管理DMA的操作是操作系统的工作,比如设备驱动程序,它将保证内存与cache的一致性.

3)当在cache中的数据比内存中的数据老时,称为stale.如果软件初始化DMA,使设备和RAM之间传递数据,那么软件必须告诉 CPU,cache中的条目必须失效.

4)当在cache中的数据比内存中的数据新时,称为dirty.在设备驱动程序允许一个设备经DMA从内存读数据时,它必须确保所有的dirty 条目写进内存.也叫做flushing或sync cache.


你可能感兴趣的:(内存一致性)