multithreading - 当线程被调度到不同的 CPU 内核上时,预期的内存语义(例如先读后写)会发生什么?

标签 multithreading operating-system cpu-architecture cpu-cache memory-barriers

单个线程中的代码具有一定的内存保证,例如先读后写(即将某个值写入内存位置,然后将其读回应该给出您写入的值)。

如果一个线程被重新调度以在不同的 CPU 内核上执行,这种内存保证会发生什么?假设一个线程将 10 写入内存位置 X,然后被重新调度到不同的内核。该内核的 L1 缓存可能具有不同的 X 值(来自之前在该内核上执行的另一个线程),因此现在读取 X 不会像线程期望的那样返回 10。当一个线程被调度到不同的核心上时,是否会发生一些 L1 缓存同步?

最佳答案

在这种情况下所需要的只是在进程开始在第二个处理器上执行之前,在第一个处理器上执行的写入变得全局可见。在英特尔 64 位架构中,这是通过在操作系统用来将进程从一个内核转移到另一个内核的代码中包含一个或多个具有内存栅栏语义的指令来实现的。来自 Linux 内核的示例:

/*
 * Make previous memory operations globally visible before
 * sending the IPI through x2apic wrmsr. We need a serializing instruction or
 * mfence for this.
 */
static inline void x2apic_wrmsr_fence(void)
{
    asm volatile("mfence" : : : "memory");
}

这确保在执行将启动在新内核上运行的线程的处理器间中断之前,来自原始内核的存储是全局可见的。

引用:英特尔架构软件开发人员手册(文档 325384-071,2019 年 10 月)第 3 卷的第 8.2 和 8.3 节。

关于multithreading - 当线程被调度到不同的 CPU 内核上时,预期的内存语义(例如先读后写)会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60081485/

相关文章:

multithreading - Racket 支持多线程吗?

c++ - 快速的线程间通信机制

java - 关于java同步的理解和困惑

python - os.listdir 未读取所有文件

c - Linux中为CFS定义的函数在哪里

c++ - int32_t 的延迟是否低于 int8_t、int16_t 和 int64_t?

c++ - 为指令集模拟器设计高效内存

c++ - 何时使用 C++11 mutex、lock、unique_lock、shared_lock 等

c - 需要说明汇编器和Linux信号处理的用法

caching - 组关联缓存的缓存命中率 : I don't understand this diagram