10

如果 MESI 协议阻止其他内核写入“独占”拥有的数据,x86 LOCK 前缀的目的是什么?

我对 LOCK 提供的内容和 MESI 提供的内容感到有些困惑?

我了解 MESI 协议是关于确保所有内核都看到一致的内存状态,但据我了解,它还可以防止内核写入另一个内核已经写入的内存?

4

2 回答 2

7

MESI 协议使内存缓存有效地不可见。这意味着多线程程序不必担心一个核心从它们那里读取过时的数据,或者两个核心写入缓存线的不同部分,然后将一半的写入和另一半的一半发送到主内存。

但是,这对诸如递增、比较和交换等读-修改-写操作没有帮助。MESI 协议不会阻止两个内核各自读取相同的内存块,每个内核都添加一个,然后每个内核都写回相同的值,从而将两个增量变为一个。

在现代 CPU 上,LOCK 前缀锁定高速缓存行,因此读-修改-写操作在逻辑上是原子的。这些都过于简单化了,但希望他们能给你这个想法。

解锁增量:

  1. 获取缓存行,可共享就可以了。读取值。
  2. 将读取值加一。
  3. 获取缓存行独占(如果不是 E 或 M)并锁定它。
  4. 将新值写入缓存行。
  5. 将缓存行更改为已修改并解锁。

锁定增量:

  1. 获取缓存行独占(如果不是 E 或 M)并锁定它。
  2. 读取值。
  3. 给它加一个。
  4. 将新值写入缓存行。
  5. 将缓存行更改为已修改并解锁。

注意到区别了吗?在未锁定增量中,缓存行仅在写内存操作期间被锁定,就像所有写操作一样。在锁定增量中,高速缓存行在整个指令中保持不变,从读操作到写操作,包括在增量本身期间。

此外,某些 CPU 具有除内存缓存之外的其他东西,它们会影响内存可见性。例如,某些 CPU 具有读取预取器或后置写入缓冲区,这可能导致内存操作执行无序。在需要时,LOCK 前缀(或其他 CPU 上的等效功能)也将做任何需要做的事情来处理内存操作排序问题。

于 2016-01-08T21:22:10.803 回答
0

是的,你混淆了两个不同的东西。MESI 协议是一种缓存一致性协议,可确保每个核心/处理器在请求时从其他处理器的缓存(或内存)中获取最新数据。如果高速缓存行处于“E”状态,则告诉请求处理器一个(并且只有一个)其他处理器具有该行的副本。仅此而已;“E”状态无论如何都不会阻止请求处理器访问数据; 它只是说明只有一个处理器拥有数据的副本(并且该副本也与内存中的副本一致)。因此,如果核心请求处于“E”状态的数据,核心将获得它的副本。“E”中的另一个副本将根据核心请求副本用于“写入”还是“读取”而更改。如果请求写入,则旧副本将失效(“I”状态),如果用于读取,则将旧副本置于共享“S”状态。

于 2016-01-08T20:51:11.680 回答