在多核上下文切换期间处理器缓存是否被刷新?

Is processor cache flushed during context switch in multicore?

最近讨论了为什么seq处有volatile标记in Java Actors demo

@volatile private var seq = 0L
private def nextSeq: Long = {
  val next = seq
  seq += 1
  next
}

一个答案是可以迁移线程并丢失变量(其他核心在其私有缓存中将具有不连贯的值)。但是,您通常不会用 volatile 标记每个变量以启用多核执行。因此,无论何时切换上下文,内核都必须刷新缓存。但是,我无法在任何地方找到明确发音的声明。每个人,例如。维基百科,只关心寄存器和栈内存

The state of the process includes all the registers that the process may be using, especially the program counter, plus any other operating system specific data that may be necessary. This data is usually stored in a data structure called a process control block (PCB), or switchframe. In order to switch processes, the PCB for the first process must be created and saved. The PCBs are sometimes stored upon a per-process stack in kernel memory (as opposed to the user-mode call stack), or there may be some specific operating system defined data structure for this information.

关于迁移通用目的,我们在现实中有什么data/variables?

每当有任何类型的上下文切换时,OS 将保存其状态,以便它可以在任何内核上再次重新启动(假设它没有使用处理器关联函数绑定到特定内核) .

保存由于某种原因不完整的状态会破坏线程或处理的全部目的,因此缓存作为切换的一部分被刷新。

Volatile 与上下文切换没有任何关系。它只是告诉编译器内存位置如有更改,恕不另行通知,因此每次源代码指示时都必须访问它,即优化访问内存位置的通常编译器行为不适用于 volatile 声明的位置。

other cores will have incoherent values in their private caches

所以默认情况下,每个处理器都有一个叫做 MESI 协议的东西,它基本上强制每个 cpu 核心在变量被单个处理器修改后刷新变量,以保持变量处于一致状态.问题是它真的很昂贵,所以 Java 编译器假设所有变量都将由单核使用。 volatile关键字禁止编译器做这个优化。