c# – Interlocked.CompareExchange是否使用内存屏障?

我正在阅读Joe Duffy发表的关于 Volatile reads and writes, and timeliness的帖子,我正在试图了解一些关于帖子中最后一个代码示例的内容:

while (Interlocked.CompareExchange(ref m_state, 1, 0) != 0) ;
m_state = 0;
while (Interlocked.CompareExchange(ref m_state, 1, 0) != 0) ;
m_state = 0;
…

当执行第二个CMPXCHG操作时,是否使用内存屏障确保m_state的值确实是写入它的最新值?或者只是使用已经存储在处理器缓存中的一些值? (假设m_state不被声明​​为volatile)。
如果我理解正确,如果CMPXCHG不会使用内存障碍,那么整个锁的获取过程将不会公平,因为第一个获取锁的线程很可能是将获得所有锁的线程的以下锁。我明白了,还是我错过了这里的东西?

编辑:主要的问题是在尝试读取m_state的值之前,调用CompareExchange是否会导致内存障碍。所以当他们再次尝试调用CompareExchange时,分配0是否对所有线程都可见。

任何具有锁定前缀的x86指令都具有完整的内存屏障。如Abel的答案所示,Interlocked * API和CompareExchanges使用锁定前缀的指令,例如lock cmpxchg。所以,它意味着内存围栏。

是的,Interlocked.CompareExchange使用内存障碍。

为什么?因为x86处理器这样做。从英特尔Volume 3A: System Programming Guide Part 1第7.1.2.2节:

For the P6 family processors, locked operations serialize all outstanding load and store operations (that is, wait for them to complete). This rule is also true for the Pentium 4 and Intel Xeon processors, with one exception. Load operations that reference weakly ordered memory types (such as the WC memory type) may not be serialized.

波动与本次讨论无关。这是关于原子操作;为了支持CPU中的原子操作,x86保证所有以前的加载和存储完成。

相关文章
相关标签/搜索