Ale*_*lex 2 concurrency x86 multithreading x86-64 cpu-cache
众所周知,现代x86_64上的所有缓存L1 / L2 / L3级别都是虚拟索引的,并进行了物理标记。并且所有内核都通过QPI / HyperTransport上的高速缓存一致性协议MOESI / MESIF通过最后一级高速缓存-L3进行通信。
例如,Sandybridge系列CPU具有4至16路高速缓存L3和page_size 4KB,那么这允许在并发进程之间交换数据,并发进程通过共享内存在不同内核上执行。这是可能的,因为高速缓存L3不能同时包含与进程1的页面和与进程2的页面相同的物理内存区域。
这是否意味着每次进程1请求相同的共享内存区域时,进程2会将其页面的缓存行刷新到RAM中,然后进程1加载与页面的缓存行相同的内存区域在process-1的虚拟空间中?真的很慢还是处理器使用了一些优化?
现代的x86_64 CPU是否使用相同的缓存行,而不进行任何刷新,以通过共享内存在具有不同虚拟空间的2个进程之间进行通信?
Sandy Bridge Intel CPU-缓存L3:
低19位-对确定当前设置的数字有效
4 KB-标准页面大小
我们有7个丢失的位[18:12]-即我们需要检查(7 ^ 2 * 16位)= 1024个缓存行。这与1024路缓存相同-因此非常慢。这是否意味着缓存L3(已物理索引,已物理标记)?
标签虚拟地址中丢失位的摘要(页面大小8 KB-12位):
它应该是:
这是可能的,因为高速缓存L3不能同时包含与进程1的页面和与进程2的页面相同的物理内存区域。
啊,啥?如果两个进程都映射了页面,则它们都可以命中高速缓存中的同一行物理内存。
这是使用大型内置三级缓存的英特尔多核设计的部分优势。一致性只需要检查L3标签,即可在另一个内核的L2或L1缓存中找到E或M状态的缓存行。
在两个内核之间获取数据仅需要写回L3。我忘记了在哪里记录。也许http://agner.org/optimize/。我认为Nehalem之前的每个内核都有单独的缓存的CPU我认为必须刷新到DRAM以获得一致性。IDK(如果可以使用与检测一致性问题相同的协议直接将数据从高速缓存发送到高速缓存)。
映射到不同虚拟地址的同一缓存行将始终位于L1缓存的同一集合中。请参阅注释中的讨论:L2 / L3高速缓存在物理上具有索引并在物理上具有标记,因此混叠永远不会成为问题。(只有L1可以从虚拟索引中获得速度上的好处。只有在地址转换完成之后才能检测到L1缓存未命中,因此可以及时准备物理地址以探查更高级别的缓存。)
另请注意,注释中的讨论错误地提到了Skylake降低L1缓存的关联性。实际上,与以前相比,Skylake L2缓存的关联性更低(4路,低于SnB / Haswell / Broadwell中的8路)。L1仍然像往常一样是8路32kiB:关联性的最大大小,使分页选择地址位不在索引之内。因此,毫无疑问。
另请参见关于此问题的另一个答案,该问题是关于同一内核上通过L1通信的HT线程的信息。我说了更多有关缓存方式和设置的内容。(感谢Voo,我只是更正了它,说缓存索引选择了一个集合,而不是一种方式。:P)