内核如何决定在MESI中使哪个缓存行无效?

时间:2018-02-25 00:39:15

标签: assembly x86-64 cpu-architecture cpu-cache

我对缓存行有一些误解。我正在使用HaswellUbuntu。现在让我们说我们有2线程应用程序,其中发生以下情况。

mov [addr], dword 0xAC763F
;starting Thread 1 and Thread 2

现在让我们说线程并行执行以下操作:

Thread 1                        Thread 2
mov rax, [addr]              mov rax, [addr]
mov [addr], dword 1     mov [addr], dword 2

现在我对正在发生的事情的理解是:

  1. 在开始之前,主线程写入相应的缓存行(addr)并将其标记为Exclusive
  2. 如果在开始wrtining之前,两个线程Thread 1Thread 2都已完成读取,则缓存行在所有缓存中都具有状态Shared
  3. 现在,如果Invalid中的mov [addr], dword 1Thread 1中的mov [addr], dword 2都标记为Thread 2,我就无法理解这一行的标记为MESI发生了#34;同时#34;。

    首先"同时"感觉有点模糊。我认为这是"在相同的CPU时钟周期内#34;。 ShmKEY = ftok(".", 'x'); 协议实现如何解决这个问题"同时从不同的线程编写问题"。

1 个答案:

答案 0 :(得分:4)

  

我认为这是"在相同的CPU时钟周期内#34;

不同的核心可以使用不同的时钟;例如一个核心可以是4GHz,而另一个核心是800MHz。 (但仅适用于Haswell Xeon;双核/四核部件在单个时钟域中具有所有内核。我已经读过它,它与您在空闲核心上查看CPU频率时所看到的相匹配,而一个核心是忙。)

相关:What happens when different CPU cores write to the same RAM address without synchronization?是一个非常相似的问题。 (但那个问题的OP并不知道MESI是什么)。不过,我在那里详细介绍了发送RFO请求的情况,所以如果这个问题太简洁,也许可以阅读答案。

  

在开始之前,主线程写入相应的缓存行(addr)并将其标记为Exclusive。

核心必须在之前将缓存行置于独占状态,然后才能对其进行修改。实际上,向L1D提交写操作会将其从Exclusive转换为Modified,而不与其他内核进行通信。 (L1D和L2是回写缓存)。

但是,是的,如果两个内核在其中任何一个写入之前读取缓存行,则它们都将处于共享状态。在收到对该线路的RFO请求的成功回复后,他们只能将该线路翻转为Exclusive。 Wikipedia's MESI article有一个状态转换图和RFO的定义。

冲突的RFO请求当然可以立即投放。他们需要多个周期才能到达另一个核心,因此商店有充足的时间在接收RFO之前,每个核心都会发起一个RFO。 (并不是说会阻止核心发送自己的RFO;写入无效的共享线路需要RFO才能使其进入独占状态,以便商店可以提交。)

我并非100%确定哪个请求获胜的决定将在L3缓存中决定。但

Haswell的L3包含在内,用作一致性流量的后备/过滤器。 L3不是实际广播所有核心的所有请求,而是包含标签的额外信息,以跟踪哪些核心(可能)具有哪条线路的副本。 L1和L2是私有的每个核心,因此L3是第一个共享的缓存级别。

我猜测L3会处理核心RFO首先完成的仲裁,因为它已经跟踪哪些核心(可能)需要查看哪些核心RFOs。据推测,这是在保存相关物理地址的L3片段中完成的。

As @fuz points out,MESI是围绕总线拓扑而设计的,而不是一个路由消息的更复杂的网络。英特尔的设计具有相同的状态,但实际上并不像通常的CPU架构描述那样简单地工作。

所以,我们可以肯定地说:通过一些未知的内部机制,CPU决定首先是一个RFO 。稍后到达而第一个仍在进行往返的可能会被取消(因此核心必须稍后重试),或者它可能被缓冲。

我们知道英特尔CPU具有用于竞争原子RMW操作的硬件仲裁机制,如lock add [mem], eax。据推测,它是对同一行的多个只写访问进行仲裁的完全相同的机制,因为唯一的区别是lock ed操作在操作期间保持在行上,而不响应使持续时间的请求无效。

您可以在" uncore"的同一时钟周期内讨论到达同一L3片段的多个RFO请求。 L3使用的时钟。

在Haswell的实践中,这可能是可能的; cores are connected with a bi-directional ring bus(每路32字节宽),因此每个(非核心)时钟周期的两条消息可以到达L3缓存的任何给定片段。此外,L3的每个片段都连接到核心,因此来自该核心的请求也可以同时到达。

在这种情况下,它可能很简单:如果一个切片甚至可以在同一个周期内接收多条发往它的消息(而不是只是在环上通过),它可能是硬接线的因此,该片的三个来源之一总是获胜。