从L1缓存中缓存失效
Invalidation of the cache from L1 cache
假设有一个变量X的cache line同时上传到CPU0的L1d和CPU1的L1d。从CPU0改变X的值后,当CPU1的L1d缓存行失效时,如果CPU0有X的缓存行,CPU1就不可能从CPU0的L1d缓存中复制变量X吗?而且即使不是这样,我想知道有没有CPU0引入CPU1的情况'
您如何从副本已失效的 L1 进行复制?它不再有该行的副本。
但是无论如何,可以肯定的是,在 L1d 未命中后首先检查的地方是本地 L2,然后是共享 L3。
在 Skylake-server 或更高版本上(因此 non-inclusive L3),我认为 L3 未命中将从 DRAM 重新加载,除非该行在 Modified状态在另一个核心。
否则,在客户端芯片和更早的 Xeons 上,如果任何核心具有有效副本,则 L3 未命中是不可能的,因为它是包容性的。 (真正的旧芯片,在 Nehalem 之前,也没有包含 last-level 缓存,例如 Core2 的 L2)
另见
当您说“如果我们使一个核心中的缓存无效”时,我不确定您的意思是否只是将其从该缓存中逐出,例如为其他东西腾出空间,或者如果你的意思是 运行 像 clflush
这样的指令。或者,如果您的意思是核心做了一个存储,因此必须进行所有权读取 (RFO) 以获得该行的 MESI 独占所有权(即使所有 other 副本无效),以便它可以提交从存储缓冲区到 L1d 的存储。
描述的情况是不允许的。当处理器核心对地址执行存储时,数据将写入“存储缓冲区”,以便稍后传输到缓存。在从存储缓冲区传输数据之前,缓存需要对该行进行独占访问——一种一次只能存在于一个缓存中的状态。
三个简单的案例:
- 如果核心的缓存已经有独占访问权限(即线路处于Exclusive或Modifed状态),那么存储缓冲区可以随时将数据写入缓存。
- 如果核心的缓存有行的有效副本而没有独占访问(例如“共享”状态),存储缓冲区中新数据的存在将导致缓存生成“升级”请求线。在所有其他缓存(或目录)确认它们已使该地址的任何副本无效之前,不会授予升级到 E 或 M 状态的权限。
- 如果核心的缓存没有行的有效副本(没有地址匹配或地址匹配处于无效状态),缓存将发出“Read With Intent To Modify”请求。这将导致缓存行的当前数据(无论是在内存中还是从另一个核心缓存中的修改副本)传输到请求核心的缓存,以及系统中每个其他缓存中缓存行的无效。
如果两个核心“同时”执行存储指令,实施细节将导致两个核心之一获得独占访问权。另一个核心的请求将被“拒绝”(NACK'd),并且它将重试请求,直到第一个核心+缓存完成缓存行状态的升级和数据更新。这种机制强制对单个地址的所有存储按顺序 处理,即使它们是 发布的并发。
一般来说,用户不可能在两个内核中“同时”可靠地使某事发生(或检测它是否同时发生),但实现必须通过上面描述的序列化过程。
假设有一个变量X的cache line同时上传到CPU0的L1d和CPU1的L1d。从CPU0改变X的值后,当CPU1的L1d缓存行失效时,如果CPU0有X的缓存行,CPU1就不可能从CPU0的L1d缓存中复制变量X吗?而且即使不是这样,我想知道有没有CPU0引入CPU1的情况'
您如何从副本已失效的 L1 进行复制?它不再有该行的副本。
但是无论如何,可以肯定的是,在 L1d 未命中后首先检查的地方是本地 L2,然后是共享 L3。
在 Skylake-server 或更高版本上(因此 non-inclusive L3),我认为 L3 未命中将从 DRAM 重新加载,除非该行在 Modified状态在另一个核心。
否则,在客户端芯片和更早的 Xeons 上,如果任何核心具有有效副本,则 L3 未命中是不可能的,因为它是包容性的。 (真正的旧芯片,在 Nehalem 之前,也没有包含 last-level 缓存,例如 Core2 的 L2)
另见
当您说“如果我们使一个核心中的缓存无效”时,我不确定您的意思是否只是将其从该缓存中逐出,例如为其他东西腾出空间,或者如果你的意思是 运行 像 clflush
这样的指令。或者,如果您的意思是核心做了一个存储,因此必须进行所有权读取 (RFO) 以获得该行的 MESI 独占所有权(即使所有 other 副本无效),以便它可以提交从存储缓冲区到 L1d 的存储。
描述的情况是不允许的。当处理器核心对地址执行存储时,数据将写入“存储缓冲区”,以便稍后传输到缓存。在从存储缓冲区传输数据之前,缓存需要对该行进行独占访问——一种一次只能存在于一个缓存中的状态。
三个简单的案例:
- 如果核心的缓存已经有独占访问权限(即线路处于Exclusive或Modifed状态),那么存储缓冲区可以随时将数据写入缓存。
- 如果核心的缓存有行的有效副本而没有独占访问(例如“共享”状态),存储缓冲区中新数据的存在将导致缓存生成“升级”请求线。在所有其他缓存(或目录)确认它们已使该地址的任何副本无效之前,不会授予升级到 E 或 M 状态的权限。
- 如果核心的缓存没有行的有效副本(没有地址匹配或地址匹配处于无效状态),缓存将发出“Read With Intent To Modify”请求。这将导致缓存行的当前数据(无论是在内存中还是从另一个核心缓存中的修改副本)传输到请求核心的缓存,以及系统中每个其他缓存中缓存行的无效。
如果两个核心“同时”执行存储指令,实施细节将导致两个核心之一获得独占访问权。另一个核心的请求将被“拒绝”(NACK'd),并且它将重试请求,直到第一个核心+缓存完成缓存行状态的升级和数据更新。这种机制强制对单个地址的所有存储按顺序 处理,即使它们是 发布的并发。
一般来说,用户不可能在两个内核中“同时”可靠地使某事发生(或检测它是否同时发生),但实现必须通过上面描述的序列化过程。