x86_64 CPU 是否使用相同的缓存行通过共享内存在 2 个进程之间进行通信?

Does x86_64 CPU use the same cache lines for communicate between 2 processes via shared memory?

众所周知,现代 x86_64 上的所有缓存级别 L1/L2/L3 都是 virtually indexed, physically tagged。并且所有内核通过末级缓存 - 缓存 L3 通过使用缓存一致性协议 MOESI/MESIF 在 QPI/HyperTransport.

上进行通信

例如,Sandybridge 系列CPU 有 4 - 16 路高速缓存 L3 和 page_size 4KB,这允许通过共享内存在不同内核上执行的并发进程之间交换数据.这是可能的,因为缓存 L3 不能同时包含与进程 1 的页面和进程 2 的页面相同的物理内存区域。

这是否意味着每次当 process-1 请求相同的共享内存区域时,process-2 将其页面缓存行刷新到 RAM 中,然后 process-1 加载相同的内存区域进程 1 的虚拟 space 中页面的缓存行?真的很慢还是处理器使用了一些优化?

现代 x86_64 CPU 是否使用相同的缓存行,没有任何刷新,通过共享内存在具有不同虚拟 space 的 2 个进程之间进行通信?

Sandy Bridge Intel CPU - 缓存 L3:

我们有 7 个缺失位 [18:12] - 即我们需要检查 (7^2 * 16-way) = 1024 个缓存行。这与 1024 路高速缓存相同 - 所以速度非常慢。这是否意味着缓存 L3 是(物理索引,物理标记)?

标记虚拟地址中缺失位的摘要(页面大小 8 KB - 12 位):

应该是:

This is possible because cache L3 can't contain the same physical memory area as page of process 1 and as page of process 2 at the same time.

咦什么?如果两个进程都映射了一个页面,则它们都可以命中同一行物理内存的缓存。

这是英特尔多核设计使用大型包容性 L3 缓存的部分好处。一致性只需要检查 L3 标签以在另一个核心的 L2 或 L1 缓存中找到处于 E 或 M 状态的缓存行。

在两个核心之间获取数据只需要回写到L3。我忘记了这是在哪里记录的。也许 http://agner.org/optimize/ or What Every Programmer Should Know About Memory?。或者对于不共享任何级别缓存的核心,您需要在缓存层次结构的同一级别的不同缓存之间进行传输,作为一致性协议的一部分。即使线路“脏”也是可能的,新所有者承担最终写回与 DRAM 不匹配的内容的责任。


映射到不同虚拟地址的同一缓存行将始终位于同一组一级缓存中。请参阅评论中的讨论:L2 / L3 缓存是物理索引以及物理标记,因此别名从来都不是问题。 (只有 L1 可以从虚拟索引中获得速度优势。直到地址转换完成后才会检测到 L1 缓存未命中,因此物理地址可以及时准备好探测更高级别的缓存。)

另请注意,评论中的讨论错误地提到了 Skylake 降低了 L1 缓存的关联性。事实上,是 Skylake L2 缓存的关联性低于以前(4 路,低于 SnB/Haswell/Broadwell 中的 8 路)。 L1 仍然是 32kiB 8 路一如既往:保持页面选择地址位在索引之外的关联性的最大大小。所以毕竟没有什么神秘的。

另见 。我在那里说了更多关于缓存方式和设置的内容。