首页 > 解决方案 > 同一处理器上两个内核之间的缓存一致性问题

问题描述

有两个进程 p1 和 p2 分别在不同的内核上运行,比如 c1 和 c2(两个内核都在同一个物理处理器上)。这两个内核具有不同的 L1 和 L2 缓存,同时共享通用的 L3 缓存。p1 和 p2 都使用指针 ptr(ptr 在共享内存中)。进程 p1 初始化 ptr & p2 应该简单地使用它。在 p2 中面临崩溃,因为它最初将 ptr 视为“NULL”(尽管一段时间后,可能由于缓存一致性,p2 会看到 ptr 的正确值)。我有以下与此相关的问题:

  1. 尽管会使用某种形式的缓存一致性协议,但如何会出现上述情况(p2 看到 ptr 的值为空)?
  2. 在共享总线/内存架构的情况下,不同的处理器(在不同的套接字上)通常遵循总线侦听协议以实现缓存一致性。我想知道如果两个内核(两个内核都在同一个物理处理器上)在共享一个公共 l3 缓存的同时拥有它们的私有 l1/l2 缓存,那么缓存一致性协议是什么。
  3. 有没有办法检查正在使用的缓存一致性协议是什么(这是针对 ubuntu 16.04 系统的)?

标签: linuxubuntucachingx86intel

解决方案


x86 即使跨多个套接字也是缓存一致的(就像您可以运行的所有其他真实世界的 ISA std::thread)。x86 的内存排序模型是程序顺序 + 带有存储转发的存储缓冲区。

正式模型:更好的 x86 内存模型:x86-TSO。非正式地:http: //preshing.com/20120930/weak-vs-strong-memory-models/

缺乏连贯性绝对不是您的错误。一旦存储提交到一个内核中的 L1d 缓存,其他内核就无法加载旧值。(因为他们的行副本都已失效,所以进行修改的核心可以拥有独占所有权:MESI。)


几乎可以肯定 p2 在 p1 写入之前正在读取共享内存。 Coherence 不会自行创建同步。 如果 p1 和 p2 都异步附加到共享内存,那么在 p1 写入之前没有什么可以阻止 p2 读取。

std::memory_order_acquire在读取指针之前,您需要某种 p2 检查的数据就绪标志。或者只是旋转加载指针,直到看到一个非 NULL 值。

mo_acquire在指针的原子负载上使用以避免编译时重新排序,或在非 x86 上运行时重新排序,您稍后使用该指针访问的东西。或者实际上只mo_consume需要使用指针,但编译器将其加强为mo_acquire.这在 x86 上没问题;反正获取是免费的。)


推荐阅读