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:
- 8 MB - 缓存大小
- 64 B - 缓存行大小
- 128 K - 行(128 K = 8 MB / 64 B)
- 16路
- 8K - 路数组数(8K=128K线/16路)
- 13 位 [18:6] - 虚拟地址(索引)定义当前设置编号 (这是标记)
- 512K - 各相同(虚拟地址/512K)竞争同一套(8MB/16路)
low 19 bits - 决定当前组数重要
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(虚拟索引,物理标记)
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 路一如既往:保持页面选择地址位在索引之外的关联性的最大大小。所以毕竟没有什么神秘的。
另见 。我在那里说了更多关于缓存方式和设置的内容。
众所周知,现代 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:
- 8 MB - 缓存大小
- 64 B - 缓存行大小
- 128 K - 行(128 K = 8 MB / 64 B)
- 16路
- 8K - 路数组数(8K=128K线/16路)
- 13 位 [18:6] - 虚拟地址(索引)定义当前设置编号 (这是标记)
- 512K - 各相同(虚拟地址/512K)竞争同一套(8MB/16路)
low 19 bits - 决定当前组数重要
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(虚拟索引,物理标记)
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 路一如既往:保持页面选择地址位在索引之外的关联性的最大大小。所以毕竟没有什么神秘的。
另见