单线程在多核处理器上的数据可见性

Data visibility on multi-core processor by single thread

在单线程程序中,核心 1 中线程所做的更改如何对另一个核心 2 可见,以便在上下文切换后线程(现在 运行 在核心 2 上)将具有更新值?

考虑以下示例:

  1. 变量 x 在主内存中的值为 10。

  2. 线程在核心 1 上运行并将 x 更改为 5,它仍在缓存中并且尚未刷新到主内存,因为我们没有使用任何内存屏障。

  3. 发生上下文切换,线程从核心1移动到核心2。

  4. 线程读取x的值。

如果上下文切换后线程在核心 2 中恢复执行,x 的值是多少?

如果 "cache coherence" 管理一致性来处理上述情况,那么为什么我们需要在多线程程序中显式锁定(或任何 read/write 障碍)?

考虑到您的第一个问题,上下文切换也会保留寄存器内容。因此,即使移动到另一个核心(或 CPU),线程也会看到最新值。

但是对于多线程程序,CPU registers 对于不同的线程是不同的(不管有多少 cores线程被执行),并且寄存器不是缓存一致性的一部分。

因此,我认为,多线程程序确实需要确保寄存器中的值与主存中的值是最新的。 (缓存一致性仅确保 CPU 缓存与内存保持同步)。 因此,我想,你需要一个屏障来同步寄存器和内存。

你可以这样理解:程序本质上只在主存上运行。但是,编译器优化了对主内存的访问并使用 寄存器 进行中间操作。 因此,程序只访问内存和寄存器。 不过,CPU也引入了自己的cache的内存。 读取和写入 from/to 内存在内部(由 CPU)由缓存优化。 缓存一致性仅确保 CPU 内的缓存是最新的(因此,访问 内存 的程序获得正确的值。)

总结一下:

  • 缓存一致性确保缓存内存是最新的,它是不受程序控制,因为它在 CPU.
  • 内部
  • 上下文切换 由操作系统处理,当它把线程移动到不同的内核时确保寄存器的值正确。
  • 内存屏障确保寄存器内存是最新的,这是程序必须确保的。