缓存一致性如何在多核和多处理器架构中发挥作用?

时间:2016-02-19 17:52:11

标签: multithreading caching mesi

让我解释一下我的理解,并要求你确认其正确性或纠正我:

  1. 有一个MESI协议,它允许有效的缓存一致性(https://en.wikipedia.org/wiki/MESI_protocol)。它是最先进的机制。
  2. 对于单个处理器的多个内核,MESI通过L3缓存进行操作,该缓存在处理器的内核之间共享。
  3. 对于多个处理器(没有共享L3),MESI通过主存储器运行。
  4. 当使用由多个线程读取和写入的全局变量时, volatile 类型说明符用于防止不需要的优化以及防止寄存器中的缓存(<在L1-3缓存中强>不)。因此,如果值不在寄存器中但在缓存或主内存中,MESI将完成其工作以使线程看到正确的全局值。

1 个答案:

答案 0 :(得分:1)

  

对于单个处理器的多个内核,MESI通过L3缓存进行操作,该缓存在处理器的内核之间共享。

MESI在所有缓存级别运行。在某些处理器设计中,L3缓存可用作高效的交换机&#34;核心之间。例如,如果L3缓存是包容性的并且将所有内容保存在任何CPU的L1或L2缓存中,那么只知道L3缓存中的某些东西不足以知道它不在任何CPU缓存中。其他核心的缓存。这可以减少所需的窥探量。这些都是复杂的优化。

  

对于多个处理器(没有共享L3),MESI通过主存储器运行。

我不确定你在这里要说的是什么,但它似乎并不符合任何真实情况。 MESI在缓存之间运行。内存不是缓存,因此不需要参与MESI协议。

您可能意味着对于没有L3缓存的CPU,L2缓存间MESI流量发生在与连接到主内存的CPU总线相同的CPU总线上。在CPU具有片上存储器控制器之前,这曾经适用于某些多芯片CPU设计。但是今天,大多数笔记本电脑/台式机多核CPU都安装在内存控制器上,因此连接内存的总线只能连接到内存。所以那里没有MESI流量。如果数据在一个核心的L2缓存中并且必须到达另一个核心的L2缓存,则它不会越过内存。 (想想核心和内存控制器的拓扑结构,这将是疯狂的。)

  

当使用由多个线程读取和写入的全局变量时,volatile类型说明符用于防止不需要的优化以及防止寄存器中的缓存(不在L1-3缓存中)。

我知道没有语言这是真的。在C / C ++中肯定不是这样,volatile用于信号而非多线程(至少在平台上有明确定义的多线程API)。对于Java这样的事情来说并不正确,volatile具有与寄存器无关的特定语言语义。

  

因此,如果值不在寄存器中但在高速缓存或主存储器中,则MESI将完成其工作以使线程看到正确的全局变量值。

在硬件/汇编程序级别可能是这样。存在寄存器的地方。但实际上并不是因为虽然MESI使内存缓存连贯,但现代CPU还有其他优化方法可以产生相同类型的问题。例如,CPU可能会预取读取操作,也可能会导致写入无序延迟。所以除了MESI之外你还需要记忆障碍等东西。当然,这非常适合平台。

您可以将MESI视为优化。您仍然必须执行平台所需的任何操作才能使线程间内存可见性正常工作。但MESI极大地减少了这项工作。

例如,如果没有MESI,您可能有一种设计,其中数据从一个核心到另一个核心的唯一方法是通过写入主存储器,然后等待写入完成,然后从主存储器读取。那将是一场灾难。首先,您需要将内容刷新到主内存,以防其他线程需要它。其次,所有这些流量都会扼杀常规内存流量。呸。