.net 联锁的.Xxx方法是否保证在所有数据缓存中更新值?

.net 联锁的.Xxx方法是否保证在所有数据缓存中更新值?,.net,multithreading,.net,Multithreading,例如: Thread a: Interlocked.Increment(ref x); Thread b: int currentValue = x; 假设线程b在线程a之后执行,线程b中的“currentValue”是否保证为递增值?或者,线程b是否需要执行thread.volatireRead(ref x)?技术上取决于.NET所运行的CPU,但对于任何公共CPU,答案都是肯定的,对于联锁的.Increment,缓存一致性是有保证的。它符合MESI的要求 CPU可以在其缓存中有一条无

例如:

Thread a:  Interlocked.Increment(ref x);

Thread b:  int currentValue = x;

假设线程b在线程a之后执行,线程b中的“currentValue”是否保证为递增值?或者,线程b是否需要执行thread.volatireRead(ref x)?

技术上取决于.NET所运行的CPU,但对于任何公共CPU,答案都是肯定的,对于联锁的.Increment,缓存一致性是有保证的。它符合MESI的要求

CPU可以在其缓存中有一条无效的行,但它还不知道该行无效-无效队列包含尚未执行的无效。(无效队列位于缓存的另一端;CPU不能扫描它,因为它可以存储缓冲区)。因此,需要内存屏障

(x86)

MOESI(用于AMD64芯片)非常类似:


(AMD64)

据我所知,只有通过其他联锁方法访问时,才能保证联锁。当谈到x86系统上的64位值时,这一点可能特别重要,因为无法保证它是原子的,所以会出现值撕裂的问题。可靠读取可通过联锁更改的值的一个好方法是CompareExchange:

int val = Interlocked.CompareExchange(ref field, 0, 0);

这会将
字段的值
变为0,但仅当旧值为0时,否则不会执行任何操作。无论哪种方式,都会返回旧值。因此,基本上:它读取值而不改变它,与其他互锁方法相比是安全的。

这一点很好,但并不直接解决缓存一致性问题。据我所知,缓存保证在任何时间点都是一致的。但是,当在没有联锁的情况下读取时,没有内存屏障来防止值被撕破。不过,我对这一点的理解是不完整的。如能提供进一步说明,我将不胜感激。