易失性,在 x86 处理器上没有用处
我在某处读到 x86 处理器具有缓存一致性,并且可以在每次写入时跨多个内核同步字段的值。
这是否意味着如果我们计划仅在 x86 处理器上运行,我们可以在不使用 java 中的“易失性”关键字的情况下进行编码?
更新:
好吧,假设我们忽略指令重新排序的问题,我们是否可以假设 x86 处理器上不存在跨内核不可见的非易失性字段的分配问题?
I read somewhere that x86 processors have cache coherency and can sync the value of fields across multiple cores anyway on each write.
Does that mean that we can code without using the 'volatile' keywoard in java if we plan on running only on x86 processors?
Update:
Ok assuming that we leave out the issue of instruction reordering, can we assume that the issue of an assignment to a non-volatile field not being visible across cores is not present on x86 processors?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
不——
易失性
关键字不仅仅具有缓存一致性的含义;它还对运行时可以执行和不能执行的操作进行限制,例如延迟构造函数调用。No -- the
volatile
keyword has more implications than just cache coherency; it also places restrictions on what the runtime can and can't do, like delaying constructor calls.关于您的更新:不,我们不能。其他线程可以只读取过时的值而不更新变量。还有一个问题:只要能够保证单线程行为正确,JVM 就可以优化代码。
这意味着:
如果愿意的话,可以通过 JIT 优化为 while(true)!
About your update: No we can't. Other threads could just read stale values without the variable being updated. And another problem: The JVM is allowed to optimize code as long as it can guarantuee that the single threaded behavior is correct.
That means that something like:
can be optimized by the JIT to while(true) if it wants to!
可以同步字段的值
和始终同步字段的值
之间存在很大差异。如果你有 volatile,x86 可以同步字段,否则它不会也不应该同步。注意:易失性访问可能比非易失性访问慢 10-30 倍,这是不总是执行易失性访问的一个关键原因。
顺便说一句:您知道有哪些多核、普通 x86 处理器吗?我本以为大多数都是支持 x86 的 x64。
There is a big difference between
can sync the value of fields
andalways syncs the value of fields
. x86 can sync fields if you have volatile, otherwise it doesn't and shouldn't.Note: volatile access can be 10-30x slower than non-volatile access which is a key reason it is not done all the time.
BTW: Do you know of any multi-core, plain x86 processors. I would have thought most were x64 with x86 support.
关于 JVM 应如何应对 易失性 有非常精确的规范,如果它选择使用特定于 cpu 的指令来执行此操作,那么对您有好处。
您唯一应该说“我们知道在这个平台上 cpu 的行为就像......”的地方是在本机代码中链接时需要符合 cpu。在所有其他情况下,请写入规范。
请注意,对于编写在多个 cpu 上运行的健壮代码(每个 cpu 都有自己的缓存)来说,易失性关键字非常重要,因为它告诉 JVM 忽略本地缓存并获取官方值,而不是 5 分钟前的缓存值。你通常想要那样。
There are very exact specifications on how the JVM should behave for
volatile
and if it choose to do that using cpu-specific instructions then good for you.The only place where you should say "we know that on this platform the cpu behaves like.." is when linking in native code where it needs to conform to the cpu. In all other cases write to the specification.
Note that the volatile keyword is very important for writing robust code running on multiple cpu's each with their own cache, as it tells the JVM to disregard local cache and get the official value instead of a cached value from 5 minutes ago. You generally want that.
字节码的写入甚至不必导致机器代码的写入。除非它是易失性写入。
a write in bytecode doesn't even have to cause a write in machine code. unless it's a volatile write.
我可以保证
volatile
有一定的用处。我曾经遇到过这样一种情况:一个线程的变量为“null”,而另一个线程的变量具有在该线程中设置的正确值。调试并不好玩。对所有共享字段使用 volatile :)I can vouch for
volatile
having some use. I've been in the situation where one thread has 'null' for a variable and another has the proper value for the variable that was set in that thread. It's not fun to debug. Use volatile for all shared fields :)