问题标签 [mesi]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
caching - MESI 协议中的 L3$ 角色部分是什么
我想在 intel Broadwell 中了解 MESI 的更多细节。
假设一个 cpu socket 有 6 个核心 core 0 到 core 5 ,每个都有自己的 L1$ 和 L2$ 并共享 L3$ ,在共享内存中有一个 var X , x 位于缓存行中,称为 XCacheL ,以下是我的问题的详细信息:
T1:核心 0 和核心 4 和核心 5 的 x = 100 并且 XCacheL处于共享状态,因为 3 个核心具有 XCacheL 的副本。
T2:核心0需要修改x,所以核心0广播无效信号,核心4和核心5接收到信号,使他们的XCacheL副本无效,核心0修改x为200,现在XCacheL状态被修改。
T3:核心 4 需要读取 x,但其 XCacheL 副本在 T2 中无效,因此它会触发读取未命中,将发生以下情况:
所以在 T3 之后,XCacheL 是核心 0 和核心 4 状态:共享,并且I在核心 5 中无效,并且 L3$ 和主内存具有最新的有效 XCacheL。
T4:核心 5 需要读取 x ,因为它的 XCacheL 副本在T2 中无效,但是这个 monent XCacheL 在 L3$ 中有正确的副本,核心 5 是否需要像核心 4 一样触发读取未命中?!
我的猜测是:不需要,因为 L3$ 具有有效的 XCacheL,所以核心 5 可以达到 L3$ 并在核心 5 中从 L3$ 到 L1$ 获得正确的 XCacheL,因此核心 5 不会触发读取未命中。
caching - MESI 协议 snoop 实现问题
我有一个 MESI 协议问题。假设我有两个核心(核心 1 和 2),每个核心都有自己的二级缓存。当两个内核具有相同的数据并且缓存线处于状态 S 时,这意味着它们都具有干净且相同的数据。在 t=0 时,核心 1 写入缓存行,核心 1 将切换到 M(已修改),核心 2 最终将处于 I(无效)状态。在物理世界中,此交易需要时间才能完成。假设缓存 2 需要 5 秒才能知道缓存 1 更新了缓存行。
假设在 t=2 时,核心 2 写入相同的缓存行并切换到 M 状态。来自核心 2 的写入操作将在 t=7 (2+5) 时通知核心 1。然后核心 2 需要在 t=5 时使缓存 2 无效,而核心 1 在 t=7 时使该行无效。现在两条线都失效了,核心1和核心2写入的数据丢失了。这显然不遵循协议。我的逻辑有什么问题以及如何防止这种废话?
cpu - 如果在独占缓存访问期间发生写操作,为什么会有数据竞争?
我正在阅读有关 MESI 协议的内容,如果我们对每个写入操作都具有独占访问权限,从而导致其他内核缓存中的缓存行无效,那么为什么会出现数据竞争?在这个例子中:
据说总体结果是变量仅增加一次,而两个内核都尝试增加它(结果预计为两个)。所以问题是,如果在写入操作期间,两个内核都请求独占访问缓存行(因此其他内核“等待”轮到他们修改并因此也获得独占访问)为什么该变量存在数据竞争?
x86 - 为什么MESI协议不能保证没有LOCK前缀的x86上CMPXCHG的原子性?
我了解 MESI 协议成功地保证了不同内核的内存(缓存)视图相同。我的问题来自这样一个事实,即在编写过程中,MESI 保证缓存由 CPU 独占,然后原子 CMPXCHG 只是原子地比较和交换值。那么,既然我们已经从 MESI 协议中获得了保证,为什么我们还需要使用 LOCK 指令来锁定缓存行呢?
multithreading - 在 x86 cpu 中窥探内存访问
我正在阅读有关缓存控制协议的信息,因为它记录在Intel Manual Vol.3(p11)
. 尚不清楚的是窥探内存访问。这是它的描述:
从 P6 系列处理器开始,如果一个处理器(通过监听)检测到另一个处理器正在尝试访问它在其缓存中修改但尚未写回系统内存的内存位置,则监听处理器将向另一个处理器发出信号处理器(通过
HITM#
信号)高速缓存行保持在修改状态,并将执行修改数据的隐式写回。隐式回写直接传送到初始请求处理器,并由内存控制器窥探,以确保系统内存已更新。在这里,具有有效数据的处理器可以将数据传递给其他处理器,而无需实际将其写入系统内存;然而,监听这个操作并更新内存是内存控制器的责任。
考虑以下缓存状态(根据 MESI):
CPU2
写入Line1
.
这就是我看到窥探的方式:
CPU2
对缓存在 中的内存执行写入操作Line1
。CPU1
窥探并发现CPU2
.CPU1
用信号通知其他CPU
sHITM#
处于Line1
修改状态CPU1
执行Line1
数据回写或 因为CPU1
此时有有效数据,数据将被传输到两者CPU2
并CPU3
传输Line1
到共享(S)状态。CPU2
在修改 (M) 状态和无效 (I) 状态中执行实际写入传输Line1
在其缓存中。Line1
CPU1
CPU3
因此,通过窥探内存访问,系统总线访问可以避免保持高速缓存的一致性,即使在某些 CPU 写入位于缓存Invalid
队列中的内存位置的情况下也是如此。这基本上就是他们所说的窥探的意思吗?
cpu-architecture - 在 MESI 缓存一致性协议中,如果需要从内存中获取数据,缓存行的状态究竟何时发生变化?
在MESI协议中当一个CPU:
- 执行读取操作
- 发现缓存行处于无效状态
- 其他缓存中没有其他非无效副本
它需要从内存中获取数据。这将需要一定数量的周期才能做到这一点。那么高速缓存行的状态是立即从(I)变为(E)还是仅在从内存中获取数据之后?
caching - MESI独占状态的优势?
我知道对于 MSI,如果我们有一块内存处于共享状态,即使没有其他人使用它,我们也必须广播我们正在修改的内容。这是 MESI 解决的问题。
但是,当我们确实使用 MESI 时,当从无效变为独占时,我们需要广播我们要读取此内容,并等待如果没有 HIT 响应。这怎么好?
c++ - MESI 协议和 std::atomic - 它是否确保所有写入对其他线程立即可见?
关于std::atomic
,存储到原子变量的 C++11 标准状态将在“合理的时间内”对该变量的加载可见。
从 29.3p13 开始:
实现应该使原子存储在合理的时间内对原子负载可见。
但是我很想知道在处理基于 MESI 缓存一致性协议(x86、x86-64、ARM 等)的特定 CPU 架构时实际发生了什么。
如果我对 MESI 协议的理解是正确的,一个核心总是会立即读取另一个核心之前写入/正在写入的值,可能是通过窥探它。(因为写一个值意味着发出一个 RFO 请求,这反过来又使其他缓存行无效)
这是否意味着当线程 A 将值存储到 a 时std::atomic
,另一个连续对该原子进行加载的线程 B 实际上总是会观察 A 在 MESI 架构上写入的新值?(假设没有其他线程对该原子进行操作)
“成功”是指在线程 A 发出原子存储之后。(修改顺序已更新)
cpu-architecture - 缓存 MOSI 协议:为什么发生写未命中时块应该提供数据
我正在阅读计算机体系结构:一种定量方法,我对以下段落感到困惑(第 5 版 - 第 415 页):
” 一个常见的协议优化是引入一个拥有状态(通常表示为 O)。拥有状态的行为类似于共享状态,因为节点只能读取拥有的块。但它的行为类似于修改状态,因为节点必须提供数据其他节点对拥有块的读取和写入未命中。对处于修改或拥有状态的块的读取未命中向请求节点提供数据并转换到拥有状态。对处于修改或拥有状态的块的写入未命中提供数据到请求节点并转换到状态无效。这种优化的 MOSI 协议仅在节点替换状态为 Modified 或 Owned 的块时更新内存。
我的问题是:为什么发生写未命中时应该将旧数据提供给请求节点?
我所做的努力:我阅读了一个相关问题。我不太明白这个问题的答案,尤其是“保持旧数据可用允许在没有正确性问题的情况下推测性地发送写未命中请求(如无序执行或预取写入)。 ”但是我仍然认为我的问题有所不同,因为旧数据不是写回内存而是写到请求节点(我猜应该是缓存?)。
x86 - 现代 x86 CPU 使用什么缓存一致性解决方案?
我对缓存一致性系统在现代多核 CPU 中的功能有些困惑。我已经看到基于侦听的协议(例如基于 MESIF/MOESI 侦听的协议)已在 Intel 和 AMD 处理器中使用,另一方面,基于目录的协议对于多核似乎效率更高,因为它们不广播而是发送消息到特定节点。
什么是 AMD 或 Intel 处理器中的现代缓存一致性解决方案,它是基于侦听的协议(如 MOESI 和 MESIF),还是仅基于目录的协议,还是两者的组合(基于侦听的协议,用于同一节点内的元素之间的通信和基于目录的节点到节点通信)?