LOCK前缀vs MESI协议?

use*_*112 8 cpu x86 multithreading locking mesi

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

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

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

Dav*_*rtz 6

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

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

在现代 CPU 上,LOCK 前缀锁定缓存行,以便读取-修改-写入操作在逻辑上是原子的。这些过于简单化了,但希望它们能给你一个想法。

解锁增量:

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

锁定增量:

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

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

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

  • 谢谢!现在我明白你的意思了——CPU 可以自由地增加其寄存器中变量的值,而无需修改缓存行。然后每个都可以连续写入结果。 (4认同)
  • “我应该说缓存一致性使用 Lock 前缀,还是 Lock 前缀使用缓存一致性?” 我的腰带应该用来支撑我的裤子。但我的裤子有环可以固定腰带。谁是真正的英雄?(安息吧,米奇·赫德伯格。我曾经想念他。(我现在仍然想念他,但我以前也想念他。)) (2认同)

wal*_*eed 0

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