intel core i7处理器使用了哪种缓存映射技术?

Which cache mapping technique is used in intel core i7 processor?

我了解了不同的缓存映射技术,例如直接映射和完全关联或集合关联映射,以及它们之间的权衡。 (Wikipedia)

不过我很好奇现在Intel酷睿i7和AMD处理器用的是哪个?

这些技术是如何演变的?还有哪些需要改进的地方?

Direct-mapped缓存在现代high-performanceCPUs中基本不用。对于相同大小的 set-associative 高速缓存,命中率的巨大优势抵消了功耗节省,控制逻辑的复杂性略高。现在的晶体管预算非常大。

对于软件来说,至少有几个彼此相距 4k 倍数的数组是很常见的,这会在 direct-mapped 缓存中造成冲突未命中。 (如果循环需要一次遍历所有数组,则调整具有多个数组的代码可能涉及倾斜它们以减少冲突未命中)

现代 CPUs 是如此之快,以至于 DRAM 延迟超过 200 个核心时钟周期,这对于强大的 out-of-order 执行 CPUs 来说太大了,无法很好地隐藏在缓存未命中。


Multi-level 缓存是必不可少的(并且全部使用 high-performance CPUs)以提供低延迟(~4 个周期) / 最热数据的高吞吐量(例如 up to 2 loads and 1 store per clock, with a 128, 256 or even 512-bit path between L1D cache and vector load/store execution units), while still being large enough to cache a reasonable sized working set. It's physically impossible to build one very large / very fast / highly-associative cache that performs as well as current multi-level caches for typical workloads; speed-of-light delays when data has to physically travel far are a problem. The power cost would be prohibitive as well. (In fact, power / power density is a major limiting factor for modern CPUs, see Modern Microprocessors: A 90-Minute Guide!。)

在我所知道的所有 x86 CPUs 中,所有级别的缓存(除了 uop 缓存)都被物理索引/物理标记。大多数设计中的 L1D 缓存从页面偏移量下方获取索引位,因此也是 VIPT,允许 TLB 查找与标记获取并行发生,但没有任何别名问题。因此,缓存不需要在上下文切换或任何事情上刷新。 (参见 this answer for more about multi-level caches 一般情况和 VIPT 速度技巧,以及一些实际 x86 CPUs 的一些缓存参数。)


私有 (per-core) L1D / L1I 和 L2 缓存是传统的 set-associative 缓存,通常是 8 路或 4 路 small/fast缓存。在所有现代 x86 CPU 上,缓存行大小为 64 字节。数据缓存是 write-back。 (AMD Bulldozer-family 除外,其中 L1D 是 write-through 和一个小的 4kiB write-combining 缓冲区。)

http://www.7-cpu.com/ has good cache organization / latency numbers, and bandwidth, and TLB organization / performance numbers, for various microarchitectures, including many x86, like Haswell.

Intel Sandybridge-family 中的“L0”decoded-uop 缓存是 set-associative 并且虚拟寻址。最多 3 个块(最多 6 微指令)可以缓存来自 32 字节机器代码块中的指令的解码结果。相关:Branch alignment for loops involving micro-coded instructions on Intel SnB-family CPUs。 (uop 缓存是 x86 的一大进步:x86 指令是 variable-length 并且难以快速/并行解码,因此缓存内部解码结果以及机器码 (L1I$) 具有显着的功率和吞吐量优势. 仍然需要强大的解码器,因为 uop 缓存不大;它在循环(包括中型到大型循环)中最有效。这避免了 Pentium4 错误(或基于当时的晶体管大小的限制)具有弱解码器和依赖跟踪缓存。)


现代英特尔(我假设是 AMD)L3 aka LLC aka last-level 缓存使用的索引功能不仅仅是地址位范围。它是一个哈希函数,可以更好地分布事物以减少固定步幅的冲突。 According to Intel my cache should be 24-way associative though its 12-way, how is that?.


从 Nehalem 开始,英特尔使用了大型包容性 共享 L3 缓存,它过滤内核之间的一致性流量。即,当一个核心读取另一个核心的 L1d 中处于修改状态的数据时,L3 标签说明是哪个核心,因此 RFO(为所有权读取)只能发送到该核心,而不是广播。 How are the modern Intel CPU L3 caches organized?. The inclusivity property is important, because it means no private L2 or L1 cache can have a copy of a cache line without L3 knowing about it. If it's in Exclusive or Modified state in a private cache, L3 will have Invalid data for that line, but the tags will still say which core might have a copy. Cores that definitely don't have a copy don't need to be sent a message about it, saving power and bandwidth over the internal links between cores and L3. See Why On-Chip Cache Coherence Is Here to Stay 有关 on-chip 英特尔“i7”中缓存一致性的更多详细信息(即 Nehalem 和 Sandybridge-family,它们是不同的体系结构,但确实使用相同的缓存层次结构)。

Core2Duo 有一个共享的 last-level 缓存 (L2),但在 L2 未命中时生成 RFO (Read-For-Ownership) 请求时速度很慢。因此,具有适合 L1d 的小缓冲区的内核之间的带宽与不适合 L2 的大缓冲区(即 DRAM 速度)一样慢。当缓冲区适合 L2 而不是 L1d 时,大小范围很快,因为写入核心将其自己的数据逐出到 L2,其他核心的负载可以在不生成 RFO 请求的情况下命中。 (参见 Figure 3.27: Core 2 Bandwidth with 2 Threads in Ulrich Drepper's "What Every Programmer Should Know about Memory". (Full version here)。


Skylake-AVX512 每个内核具有更大的 per-core L2(1MiB 而不是 256k)和更小的 L3 (LLC) 切片。不再包容。它使用网状网络而不是环形总线将核心相互连接。参见 this AnandTech article (but it has some inaccuracies in the microarchitectural details on other pages, see the comment I left)。

From Intel® Xeon® Processor Scalable Family Technical Overview

Due to the non-inclusive nature of LLC, the absence of a cache line in LLC does not indicate that the line is not present in private caches of any of the cores. Therefore, a snoop filter is used to keep track of the location of cache lines in the L1 or MLC of cores when it is not allocated in the LLC. On the previous-generation CPUs, the shared LLC itself took care of this task.

这个“snoop-filter”只有在不能有漏报时才有用。可以将无效或 RFO (MESI) 发送到没有行副本的核心。当另一个核心请求独占访问它时,让一个核心保留一行的副本是不行的。所以它可能是一个 tag-inclusive 跟踪器,它知道哪些内核可能有哪一行的副本,但不会缓存任何数据。

或者探听过滤器在不严格包含所有 L2 / L1 标签的情况下仍然有用。我不是 multi-core / multi-socket 侦听协议方面的专家。我 认为 相同的监听过滤器也可能有助于过滤套接字之间的监听请求。 (在 Broadwell 和更早版本中,只有 quad-socket 和更高版本的 Xeons 具有针对 inter-core 流量的监听过滤器;dual-socket-only Broadwell Xeon and earlier don't filter snoop requests between the two sockets。)


AMD Ryzen uses separate L3 caches for clusters of cores,所以数据在多核之间共享以便在每个集群的 L3 中复制。同样重要的是,来自一个集群中的核心的写入需要更长的时间才能对另一个集群中的核心可见,一致性请求必须通过集群之间的互连。 (类似于 multi-socket 英特尔系统中的插槽之间,其中每个 CPU 包都有自己的 L3。)

所以这为我们提供了 NUCA(Non-Uniform 缓存访问),类似于您在 multi-socket 系统中获得的通常的 NUMA(Non-Uniform 内存访问),其中每个处理器都有一个内存控制器 built-in,并且访问本地内存比访问连接到另一个插槽的内存更快。


最近的英特尔 multi-socket 系统具有可配置的侦听模式,因此理论上您可以调整 NUMA 机制以最适合您的工作负载 运行。有关可用侦听模式的 table + 说明,请参阅 Intel's page about Broadwell-Xeon


另一个进步/进化是an adaptive replacement policy in the L3 on IvyBridge and later。当某些数据具有时间局部性但工作集的其他部分大得多时,这可以减少污染。 (即,使用标准 LRU 替换在一个巨大的数组上循环将逐出所有内容,让 L3 缓存仅缓存来自数组的数据,这些数据不会很快再次被触及。自适应替换试图缓解这个问题。)


延伸阅读: