Interlocked.CompareExchange 是否使用内存屏障? [英] Does Interlocked.CompareExchange use a memory barrier?

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

问题描述

我正在阅读 Joe Duffy 的关于 Volatile 读写的帖子,以及及时性,我正在尝试了解帖子中最后一个代码示例:

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?

编辑:主要问题实际上是在尝试读取 m_state 的值之前调用 CompareExchange 是否会导致内存障碍.因此,当所有线程再次尝试调用 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.

推荐答案

任何带有 lock 前缀的 x86 指令都有完整内存屏障.如 Abel 的回答所示,Interlocked* API 和 CompareExchanges 使用 lock 前缀指令,例如 lock 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 处理器这样做了.来自英特尔的第 3A 卷:系统编程指南第 1 部分,第 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 内存类型)的加载操作可能不会被序列化.

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.

volatile 与本讨论无关.这是关于原子操作;为支持 CPU 中的原子操作,x86 保证完成所有先前的加载和存储.

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 是否使用内存屏障?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆