简体   繁体   English

"如果没有互斥,那么 volatile 如何确保发生之前的关系?"

[英]If there is no mutual exclusion then how volatile ensures happens-before relationship?

I'll hope to provide some insights in how a lock and volatile variable fit into the happens-before relation.我希望提供一些关于锁和易失性变量如何适应发生前关系的见解。

Imagine the following program with plain loads\/stores想象一下以下带有普通加载\/存储的程序

int a=0
int b=0

CPU1:
    a=1 (1)
    b=1 (2)

CPU2:
    while(b==0); (3)
    print(a) (4)

Volatile ensure happens-before relationship by two mechanisms: Volatile 通过两种机制确保发生之前的关系:

  1. If a variable is marked as volatile, then JVM implementation has to ensure that its value is never cache in L1\/L2\/L3 caches of the processor.如果一个变量被标记为 volatile,那么 JVM 实现必须确保它的值永远不会缓存在处理器的 L1\/L2\/L3 缓存中。 Value of a volatile variable must be immediately flushed to main memory. volatile 变量的值必须立即刷新到主存储器。 It is mentioned in JVM specification section 4.5<\/a> . JVM 规范第 4.5 节<\/a>中提到了它。<\/li>
  2. Updates to volatile variable happens using compare-and-swap atomic instruction.使用比较和交换原子指令更新 volatile 变量。<\/li><\/ol>"

Actually, on most multi-CPU architectures, it's kind of the other way around.实际上,在大多数多 CPU 架构上,情况正好相反。 Locking and unlocking a mutex ensures "happens-before" because a mutex treats unlock operations the same as writes to a volatile variable, and it treats lock operations the same as reads.锁定和解锁互斥锁可确保“先发生”,因为互斥锁将解锁操作视为与写入volatile变量相同,并将锁定操作视为与读取相同。

The real magic happens in hardware: Most modern processors have special memory barrier instructions that user-mode programs can use to ensure coherence between different CPU caches when it is important.真正的魔法发生在硬件中:大多数现代处理器都有特殊的内存屏障指令,用户模式程序可以使用这些指令来确保不同 CPU 缓存之间的一致性,当它很重要时。

Forcing coherence is expensive.强制一致性是昂贵的。 If the caches had to always be coherent, programs would run much more slowly.如果缓存必须始终保持一致,程序运行速度就会慢得多。 The purpose of the memory barrier instructions is to mark the parts of the program where coherence really matters, and outside of those code regions, the CPUs are free to cache data independently of each other.内存屏障指令的目的是标记程序中一致性真正重要的部分,在这些代码区域之外,CPU 可以自由地相互独立地缓存数据。

Reading and writing any volatile variable causes your program to execute memory barrier instructions that force the hardware to obey the "happens before" requirements of the Java Language Spec.读取和写入任何volatile变量会导致您的程序执行内存屏障指令,这些指令会强制硬件遵守 Java 语言规范的“发生在之前”的要求。 And, locking and unlocking any mutex also causes your program to execute the same or similar instructions.而且,锁定和解锁任何互斥体也会导致您的程序执行相同或相似的指令。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM