对于 Kprobes / Tracepoints / Uprobes:当一个进程在 CPU-2 上运行时触发了一个系统调用(例如 execve),那么附加到 sys_enter_execve 这个 Tracepoint 上的 eBPF 程序就会在 CPU-2 上执行。
此时线程B从内存读取变量V到CPU-2中,而CPU-1缓存中的变量V对线程B是不可见的 当线程A把更新后的变量V写到内存中时,线程B才可以从内存中读取到最新变量V的值 上述过程就是线程A修改变量V
如下图,线程 A 操作 CPU-1 内的变量 X 对于线程 B 操作 CPU-2 内的变量 X 就不具备可见性。
比如下图中,线程A操作的是CPU-1上的缓存,而线程B操作的是CPU-2上的缓存,很明显,这个时候线程A对变量a的操作对于线程B而言就不具备可见性了。这个就属于硬件程序员给软件程序员挖的“坑”。
当多个线程在不同的cpu上执行时,比如下图中,线程A操作的是cpu-1上的缓存,线程B操作的是cpu-2上的缓存,这个时候,线程A对变量V的操作对于线程B是不可见的。
MESI 协议),修改 putIndex 会导致其所在的 cacheline 都失效,此时假设线程 B 执行出出队操作,需要读取 takeIndex,但由于其所在的 cacheline 已经失效,所以 CPU
Redis 主进程正在 CPU-1 上运行,给客户端提供数据服务,此时 Redis 启动了子进程进行数据持久化(BGSAVE 或者 AOF),系统调度之后子进程抢占了主进程的 CPU-1,主进程被调度到 CPU -2 上去运行,导致之前 CPU-1 的高速缓存里的相关指令和数据被汰换掉,CPU-2 需要重新加载指令和数据到自己的本地高速缓存里,浪费 CPU 资源,降低性能。
比如下图中,线程 A 操作的是 CPU-1 上的缓存,而线程 B 操作的是 CPU-2 上的缓存,很明显,这个时候线程 A 对变量 V 的操作对于线程 B 而言就不具备可见性了。