2011-04-06 36 views
0

我在某处读到x86处理器具有缓存一致性,并且可以在每次写入时同步跨多个核心的字段值。是在x86处理器上无用的易失性

这是否意味着我们可以在不使用Java中的“挥发” keywoard如果我们打算只在x86处理器上运行的代码?

更新:

好的假设我们离开了指令重新排序的问题,我们可以假设一个分配不是在核可见非易失性领域的问题不会出现在x86处理器?

+0

Java是否支持DMA(如CD驱动器和内存映射I/O)? – nmichaels 2011-04-06 22:36:40

+1

你为什么?无论如何只要使用它。 – GManNickG 2011-04-06 22:37:42

+0

如果您有多个处理器,该怎么办? – biziclop 2011-04-06 22:40:43

回答

6

否 - volatile关键字已经不仅仅是高速缓存一致性更影响;它还会限制运行时可以执行和不能执行的操作,如延迟构造函数调用。

+1

具体来说,Hotspot在将代码编译为本机代码时如何优化代码。 – biziclop 2011-04-06 22:40:14

3

can sync the value of fieldsalways syncs the value of fields之间有很大的区别。如果你有易失性,x86可以同步字段,否则它不会。

注:挥发性访问可能比10-30倍的非易失性访问的是它没有这样做的所有时间的一个关键原因较慢。

顺便说一句:你知道任何多核,普通的x86处理器。我原以为大部分都是x86支持的x64。

+2

你有这个10-30x慢度的基准/例子吗?我已经在变量上使用了volatile,这些变量被读取为一个巨大的,巨大的,几乎没有,在volatile和non-volatile版本之间几乎没有性能差异。 – pdeva 2011-04-06 22:44:02

+1

如果只访问单个线程中的字段,则性能差异很小。但是,当字段在线程之间共享时,它要大得多。即缓存相当聪明。你是否积极分享线程之间的领域? – 2011-04-06 22:47:18

+2

我看到易失性访问需要26 ns,而非易失性访问需要2 ns。问题在于避免微观基准的陷阱,这些陷阱可以将一切都减少到无与伦比。 ;) – 2011-04-06 22:56:17

1

我可以保证volatile有一些使用。我一直处于这样的情况:一个线程对于变量有'null',另一个线程对于在该线程中设置的变量具有适当的值。调试并不好玩。对所有共享字段使用volatile:

2

关于JVM如何表现volatile以及它是否选择使用特定于CPU的指令来做到这一点,那么对您而言非常有用。

唯一的地方,你应该说:“我们知道,在这个平台上CPU的行为就像..”是在本地代码链接的时候需要它,以符合CPU。在所有其他情况下写入规范。

请注意,volatile关键字对于编写运行在多个CPU上并具有自己的缓存的健壮代码非常重要,因为它告诉JVM忽略本地缓存并从5分钟前获取官方值而不是缓存值。你通常需要这个。

5

关于您的更新:不,我们不能。其他线程可以只读取陈旧值而不更新变量。另一个问题是:只要JVM能够保证单线程行为是正确的,就允许JVM优化代码。

这意味着,这样的:

public boolean var = true; 
private void test() { 
    while (var) { 
     // do something without changing var 
    } 
} 

可以通过JIT进行优化,以一段时间(真),如果它想!

2

写入字节码甚至不必在机器码中写入。除非它是一个易变的写。