众所周知,与 Java 的 volatile 不同,.NET 的 volatile 允许使用来自另一个位置的以下 volatile 读取来重新排序 volatile 写入。当出现问题时 MemoryBarier
建议放在它们之间,或者Interlocked.Exchange
可以用 volatile write 代替。
它可以工作,但MemoryBarier
在高度优化的无锁代码中使用时可能会成为性能杀手。
我想了一会儿,想到了一个主意。我希望有人告诉我我是否走对了路。
所以,思路如下:
我们希望防止这两个访问之间的重新排序:
volatile1 write
volatile2 read
从 .NET MM 我们知道:
1) writes to a variable cannot be reordered with a following read from
the same variable
2) no volatile accesses can be eliminated
3) no memory accesses can be reordered with a previous volatile read
为了防止写入和读取之间不必要的重新排序,我们从刚刚写入的变量中引入了一个虚拟的 volatile 读取:
A) volatile1 write
B) volatile1 read [to a visible (accessible | potentially shared) location]
C) volatile2 read
在这种情况下,B不能用A重新排序,因为它们都访问同一个变量, C不能用B重新排序,因为两个 volatile 读取不能相互重新排序,并且C不能用 A重新排序。
问题是:
我对吗?这种虚拟易失性读取可以用作这种情况下的轻量级内存屏障吗?