【发布时间】:2011-02-25 20:12:58
【问题描述】:
Joe Duffy,给了6 rules that describe the CLR 2.0+ memory model(它是实际的实现,不是任何 ECMA 标准)我正在写下我试图解决这个问题的尝试,主要是作为一种橡胶回避的方式,但如果我的逻辑有误,至少这里有人能在它让我伤心之前抓住它。
- 规则 1:负载之间的数据依赖性 并且商店永远不会受到侵犯。
- 规则 2:所有商店都有发布语义, 即没有负载或存储可以移动 一。
- 规则 3:所有易失性负载均 获取,即没有加载或存储可能 移到前一个。
- 规则 4:无负载和 商店可能会跨越一个完整的障碍 (例如 Thread.MemoryBarrier,锁 获取,Interlocked.Exchange, Interlocked.CompareExchange 等)。
- 规则 5:加载和存储到堆 可能永远不会被介绍。
- 规则 6: 只能删除加载和存储 当合并相邻的负载和 从/到同一地点的商店。
我正在尝试理解这些规则。
x = y
y = 0 // Cannot move before the previous line according to Rule 1.
x = y
z = 0
// equates to this sequence of loads and stores before possible re-ordering
load y
store x
load 0
store z
看这个,看来load 0 可以上移到load y 之前,但是store 可能根本不会重新排序。因此,如果一个线程看到 z == 0,那么它也会看到 x == y。
如果 y 是 volatile,则加载 0 不能在加载 y 之前移动,否则它可以。不稳定的商店似乎没有任何特殊属性,没有商店可以相互重新订购(这是一个非常强大的保证!)
完整的障碍就像沙中的一条线,装载和存储无法移动。
不知道第 5 条是什么意思。
我猜规则 6 的意思是如果你这样做:
x = y
x = z
那么 CLR 就可以同时删除对 y 的加载和对 x 的第一次存储。
x = y
z = y
// equates to this sequence of loads and stores before possible re-ordering
load y
store x
load y
store z
// could be re-ordered like this
load y
load y
store x
store z
// rule 6 applied means this is possible?
load y
store x // but don't pop y from stack (or first duplicate item on top of stack)
store z
如果 y 不稳定怎么办?我在规则中看不到任何禁止执行上述优化的内容。这并不违反双重检查锁定,因为两个相同条件之间的 lock() 可以防止负载移动到相邻位置,并且根据规则 6,这是唯一可以消除它们的时间。
所以我想我理解除了规则 5 之外的所有内容。任何人都想启发我(或纠正我或在上述任何内容中添加一些内容?)
【问题讨论】:
标签: c# .net multithreading memory lock-free