【问题标题】:Where data goes after Eviction from cache set in case of Intel Core i3/i7在英特尔酷睿 i3/i7 的情况下,数据从缓存集中逐出后的去向
【发布时间】:2013-10-25 08:48:44
【问题描述】:

L1/L2 缓存包含在 Intel 中,并且 L1/L2 缓存是 8 路关联性,意味着在一个集合中存在 8 个不同的缓存行。缓存行作为一个整体操作,这意味着如果我想从缓存行中删除几个字节,整个缓存行将被删除,而不仅仅是我想要删除的那些字节。我说的对吗?

现在,我的问题是,每当 集合的缓存行被其他进程或使用 clflush(手动驱逐缓存行/块)从缓存中删除/逐出时,系统是否会存储被逐出的缓存行该缓存线的数据在某处(在任何缓冲区、寄存器等中),以便下次它可以从该位置加载数据以减少延迟,与从主存储器或更高级别的缓存加载数据相比, 总是简单地使缓存中的数据无效,然后下次从更高级别加载数据。

对文章的任何建议或任何链接都将受到高度赞赏。提前致谢。

【问题讨论】:

    标签: x86 intel cpu-architecture processor cpu-cache


    【解决方案1】:

    L1/L2 不一定包含在内,只有最后一级缓存是已知的,在 i7 上是 L3。 你说的对,缓存行是基本的缓存元素,你必须抛出一个完整的缓存行才能填充一个新的缓存行(或者当单行无效时)。您可以在此处阅读更多相关信息 - http://www.tomshardware.com/reviews/Intel-i7-nehalem-cpu,2041-10.html

    当一条线被删除时,所采取的行动取决于它的 MESI 状态(MESI 及其衍生物是缓存一致性维护的协议)。如果该行被修改,(“M”),那么数据必须“写回”到下一级缓存(如果未命中,它可能会在那里分配,或者“直写”到下一级 - 取决于在缓存维护的策略上)。请注意,当您到达最后一级缓存时,您必须点击它,因为它是包容性的。当从最后一级缓存中逐出一行时 - 它必须被写入内存。无论哪种方式,未能写回修改的行都会导致失去一致性,这很可能会导致错误执行。

    如果该行未被修改(无效、独占或共享),CPU 可能会静默丢弃它而无需写回,从而节省带宽。顺便说一句,更复杂的缓存协议(如 MESIF 或 MOESI)中还有其他几种状态。

    您可以通过谷歌搜索“缓存一致性协议”找到很多解释。如果喜欢更扎实的资料,可以参考任何CPU架构或者缓存设计教材,我个人推荐Hennessy&Patterson的《Computer Architecture, aquantitative approach》,里面有一整章讲缓存性能,不过这里有点跑题了。

    小更新:从 Skylake 开始,一些 CPU(服务器段)不再具有包容性 L3,而是非包容性(以支持增加的 L2)。这意味着干净的行也可能在 L2 老化时被写回,因为 L3 通常不保存它们的副本。

    更多详情:https://www.anandtech.com/show/11550/the-intel-skylakex-review-core-i9-7900x-i7-7820x-and-i7-7800x-tested/4

    【讨论】:

    • 感谢 leeor 的回答。我得到了这个链接,他们说 L2 和 L3 都包含在内。 bit-tech.net/hardware/cpus/2009/09/08/… 我们如何在我们自己的系统中确认 L1/L2/L3 的包含/专有属性?无论如何在命令行中或者我们需要遵循英特尔架构手册?
    • 这意味着干净的行也有可能被写回。您的意思是当从 L2 中逐出时, 行更有可能直接进入 DRAM?我不认为 SKX 浪费带宽写回干净的线条。但无论如何,很有趣。我猜想 L2 驱逐仍会在 L3 中分配而不是绕过它,因此稍后读取该数据可能会在 L3 中命中。不这样做会使 L3 成为只读缓存,其他内核请求的脏行除外。
    • 哦,在您的回答中,您确实提到了写分配策略。我认为英特尔 CPU 中的 L2 和 L3 始终为内部缓存的回写进行写分配,无论包容性如何。 (是的,L2 是不包含的,不是排他的,也就是 NINE。SKX 的 L3 也是如此)。据推测,SKX 具有包含标签的结构或某种窥探过滤器机制,以避免每次从 DRAM 加载时向所有内部缓存广播无效请求。
    • @HadiBrais,一条干净的线路不必为了正确性而被驱逐,所以我在这里要小心——例如,一些死块预测机制可能会预测一些线路可以被静默丢弃。至于失去连贯性,我是正确的。它保持 M 行而不阻塞其他会导致连贯性问题的读取。
    • @PeterCordes,你为什么不同意?请注意,我并不是说您总是分配驱逐,只是可能。实际行为可能是预测器驱动的,从他们在最新(2020 年)优化手册中的描述中可以推断:“基于访问模式、访问的代码和数据的大小以及缓存块的内核之间的共享行为,最后一级缓存可能会显示为中级缓存的牺牲品缓存" (software.intel.com/content/www/us/en/develop/download/…)
    【解决方案2】:

    L1/L2 缓存包含在 Intel 中

    就缓存包容性而言,英特尔 x86 处理器属于以下类别之一:

    • 缓存分为三个级别。 L3 包括 L2 和 L1。 L2 是 L1 的NINE(不包含,不排除)。此类别包括以下所有处理器:(1) 实现 Core 微架构的所有客户端处理器,包括 Rocket Lake,但专为客户端细分市场设计的 Core X 和 Xeon W 处理器系列除外。这还包括面向客户端的 Xeon W-10000 系列。 (2) 实现核心微架构(包括 BDX)的所有服务器处理器,以及 (3) 所有 Xeon E3、Xeon E 和 Xeon W-1200 处理器。
    • 有两级缓存。 L2 是 L1 的九个。所有 Atom 处理器(包括 Tremont)都属于这一类。所有旧的英特尔处理器(具有两个缓存级别)也属于这里。
    • 有两个级别的缓存。 L2 包括 L1D 和 L1I 的 NINE。 KNL 和 KNM 处理器属于这里。 KNC 和 KNF 的可用信息表明 L2 包含 L1,尽管这可能不准确,并且 L2 也可能仅包含这些处理器上的 L1D。有关 MCDRAM,请参见下文。
    • 缓存分为三个级别。 L3 和 L2 都是九。此类别包括以下所有处理器:(1) 所有具有三级缓存的 Pentium 4 处理器,(2) 所有代 Xeon SP 处理器,(3) Xeon D-2100、Skylake Core X 系列处理器、Skylake Xeon W 系列处理器,它们都使用 SKX 非内核而不是 SKL 非内核,以及 (4) All Tiger Lake 处理器。
    • Lakefield 处理器具有三级缓存层次结构。 4 个 Tremont 内核共享一个 NINE L2,而 Sunny Cove 内核有自己的 9 个 L2。所有 5 个内核都共享一个 LLC,该 LLC 可以配置为包容性或 NINE。

    某些处理器具有 L4 缓存或内存端缓存。这些缓存是九个。在 KNL 和 KNM 中,如果 MCDRAM 完全或部分配置为在缓存模式下运行,它会被修改为包含 L2(因此也包含 L1),这意味着包含性仅适用于 L2 中的脏行(处于 M 一致性状态) .在支持 Optane DIMM 的 CSL 处理器上,如果 PMEM DIMM 完全或部分配置为在缓存模式下运行,则 DRAM DIMM 的工作方式如下:

    Cascade Lake 处理器使用一种新颖的缓存管理方案,使用 包含和非包含 DRAM 缓存的组合以减少 DRAM 写入的带宽开销,同时还消除了复杂性 在驱逐一个处理器时管理对处理器缓存的无效 来自 DRAM 缓存的包含行。

    根据Cascade Lake: Next Generation Intel Xeon Scalable Processor.

    KNL/KNM 中的 MCDRAM 缓存和 CSL 中的 DRAM 缓存不属于三个传统包容性类别中的任何一个,即包容性、独占性和 NINE。我认为我们可以将它们描述为具有“混合包容性”。


    AMD 处理器:

    • Zen 家族:L2 是包容性的,L3 是 NINE。
    • 推土机系列:L2 为 NINE,L3 为 NINE。
    • Jaguar 和 Puma:L2 是包容性的。没有 L3。
    • K10 和 Fusion:L2 是专有的。没有 L3。
    • 山猫:我不知道 L2。没有 L3。
    • K7(型号 3 及更高型号)和 K8:L2 是专有的。没有 L3。
    • K7(型号 1 和 2)及更早版本:L2 包含在内。没有 L3。

    现有的 AMD 处理器没有 L4 缓存或 L3 之外的内存端缓存。

    威盛处理器:

    • Nano C 和 Eden C:我不知道 L2。没有 L3。
    • 所有旧处理器:L2 是独占的。没有 L3。

    这涵盖了所有当前的威盛处理器。


    L1/L2 缓存是 8 路关联性,意味着一个集合中有 8 个 存在不同的缓存行。

    在大多数英特尔处理器上都是如此。唯一的例外是 NetBurst 微体系结构,其中单个 L2 方式保存两个相邻的缓存行,统称为扇区。

    8 的关联性是典型的,但具有不同关联性的情况并不少见。例如,Sunny Cove 中的 L1D 是 12 路关联的。见:How does the indexing of the Ice Lake's 48KiB L1 data cache work?

    缓存行作为一个整体操作,意味着如果我想删除几个 来自缓存行的字节,整个缓存行将被删除,而不是 我要删除的唯一那些字节。我说的对吗?

    是的,这是由于与每个缓存级别的每个缓存条目相关联的一致性状态的限制。缓存行的所有字节只有一种状态。

    系统是否将该缓存行的逐出数据存储在某处(在 任何缓冲区,寄存器等),以便下次它可以从该位置加载数据以减少延迟

    有几个因素会影响此决定:(1) 行是否脏,(2) 较高编号缓存级别的包容性属性,如果有的话,(3) 是否预测该行将被访问不久的将来,以及(4)如果我没记错的话,如果行的内存类型在它驻留在缓存中时从可缓存更改为不可缓存,则无论之前的因素如何,它将被驱逐并且不会缓存在任何其他级别。

    所以适用于所有处理器的懒惰答案是“也许”。

    【讨论】:

    • Skylake L2 在 SKL 客户端中为 256kiB / 4 路(从 Broadwell 中的 8 路下降)或在 SKX 服务器中为 1MiB / 16 路(用于某些高端 i7 型号)。有趣的是,我不记得读过 SKX 有包含 L2 缓存。 en.wikichip.org/wiki/intel/microarchitectures/skylake_(server) 没有提到这一点。 anandtech.com/show/11550/… 声称 Skylake 客户端和服务器都具有包容性 L2 缓存(但我不太相信它,IIRC 中还有其他不准确之处。)
    • 英特尔当前的优化手册 (software.intel.com/sites/default/files/managed/9e/bc/…) 没有提到 SKX 具有包容性 L2。 According to Kanter on RWT,Haswell 有非包容性(9 个)L2,所以这对 SKX 来说是一个改变,但我们在我看过的任何东西中都没有提到这一点。
    • @PeterCordes 很好,伙计!可从InstLatx64 获得的cpuid 叶4 转储显示SKX 中的L2(和L3)是非包容性的(并且没有cpuid 勘误表)。非英特尔消息来源广泛报道称,L2 包含在这些处理器中。甚至许多研究论文都提到 L2 是包容性的。我没有想到这可能是错误的。
    • 奇怪,我想知道那一点错误信息是从哪里来的。这让我感到惊讶,因为它没有共享。我可以看到使其具有包容性的唯一原因是,如果探听过滤器只是概率性的,那么包容性 L2 可以将 L1 与核心没有的行的一些无效/写回请求隔离开来。但是,如果窥探过滤器完全跟踪所有内容,那么这并不经常适用。并且 L2 不使用大的行大小。 (顺便说一句,en.wikipedia.org/wiki/CPU_cache#Exclusive_versus_inclusive 列出了一些可能的优势)。
    • @PeterCordes 除了过滤窥探之外,使写回缓存具有包容性还有另一个潜在的好处,即使写回缓存能够有效地处理来自较低编号缓存的写回。这是可能的,因为写回永远不会在更高编号的包含缓存中丢失,因此在设计中无需处理这种情况。 (请注意,此优势不适用于直写缓存。)这正是 KNL/KNM 中的缓存模式 MCDRAM 包含修改的原因。关于 Zen/Zen2,AMD 手册确实说 L2 是包容性的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-12
    • 2013-10-09
    • 2017-08-08
    • 2014-02-14
    • 2022-01-19
    • 2012-09-28
    • 2013-01-20
    相关资源
    最近更新 更多