本文介绍了是否Interlocked.CompareExchange使用内存屏障?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在读乔·达菲的关于Volatile读取和写入,并及时,我想了解一些关于在帖子的最后code样品:

I'm reading Joe Duffy's post about Volatile reads and writes, and timeliness, and i'm trying to understand something about the last code sample in the post:

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将不使用内存屏障,那么整个锁定获取过程不会因为它极有可能这是第一次获得该锁的线程,将是将获得一个公平起见所有下面的锁。难道我理解正确的,还是我错过了什么吗?

When the second CMPXCHG operation is executed, does it use a memory barrier to ensure that the value of *m_state* is indeed the latest value written to it? Or will it just use some value that is already stored in the processor's cache? (assuming *m_state* isn't declared as volatile).
If I understand correctly, if CMPXCHG won't use a memory barrier, then the whole lock acquisition procedure won't be fair since it's highly likely that the thread that was the first to acquire the lock, will be the one that will acquire all of following locks. Did I understand correctly, or am I missing out on something here?

修改:主要的问题是实际上是否打电话来CompareExchange将试图读取m_state的前值导致内存屏障。因此,无论当他们再次尝试拨打CompareExchange分配0将是所有的线程是可见的。

Edit: The main question is actually whether calling to CompareExchange will cause a memory barrier before attempting to read m_state's value. So whether assigning 0 will be visible to all of the threads when they try to call CompareExchange again.

推荐答案

这有 preFIX任何x86指令具有的完全内存屏障。如图所示亚伯的答案,互锁* API和CompareExchanges使用锁定 - prefixed指令,如锁定CMPXCHG 。因此,这意味着存储栅栏。

Any x86 instruction that has lock prefix has full memory barrier. As shown Abel's answer, Interlocked* APIs and CompareExchanges use lock-prefixed instruction such as lock cmpxchg. So, it implies memory fence.

是,Interlocked.CompareExchange使用内存屏障。

为什么呢?由于x86处理器这样做了。从英特尔的,第7.1.2.2节:

Why? Because x86 processors did so. From Intel's Volume 3A: System Programming Guide Part 1, Section 7.1.2.2:

有关的P6系列处理器,锁定操作序列所有悬而未决的加载和存储操作(也就是说,等待他们完成)。此规则也为Pentium 4和Intel Xeon处理器真实的,但有一个例外。引用弱序内存的类型(如WC内存类型)负载操作可能无法序列化。

挥发性无关这个讨论。这是关于原子操作;支持CPU的原子操作,X86保证了所有previous负载和存储来完成的。

volatile has nothing to do with this discussion. This is about atomic operations; to support atomic operations in CPU, x86 guarantees all previous loads and stores to be completed.

这篇关于是否Interlocked.CompareExchange使用内存屏障?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-12 20:06