如果 MESI 协议阻止其他内核写入“独占”拥有的数据,x86 LOCK 前缀的目的是什么?
我对 LOCK 提供的内容和 MESI 提供的内容感到有些困惑?
我了解 MESI 协议是关于确保所有内核都看到一致的内存状态,但据我了解,它还可以防止内核写入另一个内核已经写入的内存?
如果 MESI 协议阻止其他内核写入“独占”拥有的数据,x86 LOCK 前缀的目的是什么?
我对 LOCK 提供的内容和 MESI 提供的内容感到有些困惑?
我了解 MESI 协议是关于确保所有内核都看到一致的内存状态,但据我了解,它还可以防止内核写入另一个内核已经写入的内存?
MESI 协议使内存缓存有效地不可见。这意味着多线程程序不必担心一个核心从它们那里读取过时的数据,或者两个核心写入缓存线的不同部分,然后将一半的写入和另一半的一半发送到主内存。
但是,这对诸如递增、比较和交换等读-修改-写操作没有帮助。MESI 协议不会阻止两个内核各自读取相同的内存块,每个内核都添加一个,然后每个内核都写回相同的值,从而将两个增量变为一个。
在现代 CPU 上,LOCK 前缀锁定高速缓存行,因此读-修改-写操作在逻辑上是原子的。这些都过于简单化了,但希望他们能给你这个想法。
解锁增量:
锁定增量:
注意到区别了吗?在未锁定增量中,缓存行仅在写内存操作期间被锁定,就像所有写操作一样。在锁定增量中,高速缓存行在整个指令中保持不变,从读操作到写操作,包括在增量本身期间。
此外,某些 CPU 具有除内存缓存之外的其他东西,它们会影响内存可见性。例如,某些 CPU 具有读取预取器或后置写入缓冲区,这可能导致内存操作执行无序。在需要时,LOCK 前缀(或其他 CPU 上的等效功能)也将做任何需要做的事情来处理内存操作排序问题。
是的,你混淆了两个不同的东西。MESI 协议是一种缓存一致性协议,可确保每个核心/处理器在请求时从其他处理器的缓存(或内存)中获取最新数据。如果高速缓存行处于“E”状态,则告诉请求处理器一个(并且只有一个)其他处理器具有该行的副本。仅此而已;“E”状态无论如何都不会阻止请求处理器访问数据; 它只是说明只有一个处理器拥有数据的副本(并且该副本也与内存中的副本一致)。因此,如果核心请求处于“E”状态的数据,核心将获得它的副本。“E”中的另一个副本将根据核心请求副本用于“写入”还是“读取”而更改。如果请求写入,则旧副本将失效(“I”状态),如果用于读取,则将旧副本置于共享“S”状态。