【发布时间】:2016-03-02 15:33:12
【问题描述】:
众所周知,现代 x86_64 上的所有级别的缓存 L1/L2/L3 都是 virtually indexed, physically tagged。并且所有内核通过 QPI/HyperTransport 上的缓存一致性协议 MOESI/MESIF 通过 Last Level Cache - cache-L3 进行通信。
例如,Sandybridge 系列 CPU 具有 4 - 16 路缓存 L3 和 page_size 4KB,然后这允许通过共享内存在不同内核上执行的并发进程之间交换数据。这是可能的,因为高速缓存 L3 不能同时包含与进程 1 的页面和进程 2 的页面相同的物理内存区域。
这是否意味着每次进程 1 请求相同的共享内存区域时,进程 2 将其页面缓存行刷新到 RAM 中,然后进程 1 加载与缓存相同的内存区域 -进程1的虚拟空间中的页面行数?真的很慢还是处理器使用了一些优化?
现代 x86_64 CPU 是否使用相同的高速缓存行(没有任何刷新)通过共享内存在具有不同虚拟空间的 2 个进程之间进行通信?
Sandy Bridge Intel CPU - 高速缓存 L3:
- 8 MB - 缓存大小
- 64 B - 高速缓存行大小
- 128 K - 行 (128 K = 8 MB / 64 B)
- 16路
- 8 K - 路数组(8 K = 128 K 线 / 16 路)
- 13 位 [18:6] - 虚拟地址(索引)定义当前集合编号 (这是标签)
- 512 K - 每个相同(虚拟地址 / 512 K)竞争同一组(8 MB / 16 路)
低 19 位 - 对确定当前集数很重要
4 KB - 标准页面大小
- 只有低 12 位 - 每个地址的虚拟地址和物理地址相同
我们有 7 个缺失位 [18:12] - 即我们需要检查 (7^2 * 16-way) = 1024 个缓存行。这与 1024 路缓存相同 - 所以这非常慢。这是否意味着,缓存 L3 是(物理索引,物理标记)?
标签虚拟地址缺失位汇总(页面大小 8 KB - 12 位):
- L3(8 MB = 64 B x 128 K 行),16 路,8 K 组,13 位标签 [18:6] - 缺少 7 位
- L2(256 KB = 64 B x 4 K 行),8 路,512 组,9 位标签 [14:6] - 缺少 3 位
- L1(32 KB = 64 B x 512 行),8 路,64 组,6 位标签 [11:6] - 无丢失位
应该是:
- TLB 查找后使用的 L3 / L2(物理索引、物理标记)
- L1(虚拟索引,物理标记)
【问题讨论】:
-
回复:您的编辑。不,L3 绝对没有虚拟标记。它不会在转换时刷新,并且它确实支持一致性流量。唯一的问题是它究竟是如何做到这一点的。就像我在回答中所说的那样,我最好的猜测是它被物理索引以及物理标记。出于多种原因,这很有意义,其中包括:只有 L1 缓存需要同时关心虚拟地址和物理地址。在查询更高级别的缓存时,根本只需要将物理地址发送给它们。
-
David Kanter 的文章也没有提到 L2/L3 被虚拟索引。您应该从您的问题中编辑该错误陈述(以及我在回答开始时指出的那个)。如果你有可用的物理地址,那么虚拟索引没有任何优势,所以 phys/phys 很有意义。
-
@Peter Cordes 好的,我修好了。
-
@Peter Cordes 即我们有 3 个步骤:1. 核心同时向 L1 和 TLB-L1 发送查询,并同时从两者接收答案。 2. 如果 L1 包含所需的缓存线,我们会从 L1 接收数据,然后从 TLB-L1(100 条目 * 4 KB 页面大小 = 400 KB)我们接收此缓存线的物理地址如果它在 L2/L3 中。 3. 如果 L2 或 L3 不包含它,那么我们向 TLB-L2 发送查询,不是吗?
-
不,二级 TLB 不是二级缓存的 TLB。这是TLB的第二级。如果 L1TLB 未命中,L1D$ 甚至无法检查其标签,直到 L2TLB 命中,或者发生完整的 TLB 未命中并且 CPU 遍历页表。 (并驱逐一个旧的 TLB 条目,用新找到的条目替换它。)
标签: multithreading concurrency x86 x86-64 cpu-cache