如果使用 1 个易失性变量,它是否也会关闭其他相关非易失性变量的 cpu 缓存?
问问题
174 次
3 回答
2
不,它只会阻止该变量被加载到 cpu 缓存并在那里修改。更准确地说,它强制 CPU 在访问 volatile 字段后刷新其缓存。有关更多详细信息,请参见此处
于 2013-02-20T15:47:29.263 回答
1
它不会“关闭”缓存。但是,是的,它通常会导致其他挂起写入的刷新(当您写入 a 时volatile
)或至少一些缓存失效(当您读取 a 时volatile
)......并且这两者都使用额外的内存带宽,并影响性能。
考虑这个例子:
public volatile int foo;
public int bar;
/* thread 1 */
bar = 1; // A
foo = 1; // B
/* thread 2 */
System.err.println("foo = " + foo); // C
System.err.println("bar = " + bar); // D
JLS 说 A发生在B 之前,C发生在D 之前。如果线程 2 中的 C 在线程 1 中的 B之后,则 B发生在C 之前,因此 A发生在D之前。
如果 A发生在D 之前,则在 A 处写入的值bar
必须bar
在 D 处可用……假设bar
在此期间没有其他内容写入。
具体如何实现这一点是特定于实现的。但肯定会对缓存数据产生影响……包括非易失性字段的缓存副本。
假设一个典型的内存架构,并假设线程 1 和线程 2 不共享缓存,这意味着:
- 两者都
foo
必须bar
由 B 处的线程 1 刷新到主内存,并且 foo
在 C 处,任何线程 2 的和的缓存副本都bar
必须被丢弃。
我的理解是,这通常是使用缓存无效和缓存刷新指令来实现的。
最重要的是,由于它会产生额外的内存流量,因此使用volatile
可能会对多核系统产生重大的性能影响。
于 2013-02-20T15:49:22.407 回答
0
volatile 关键字与内存无关。这是一个并发问题。
编辑 volatile 关键字与内存效率无关。这是一个并发问题。
于 2013-02-20T15:50:34.077 回答