有什么办法可以为Intel CPU 直接编写核心到核心通信的代码吗?

Is there any way to write for Intel CPU direct core-to-core communication code?

我想将线程 ping 到两个 CPU 套接字中的所有内核,并在不写回 DRAM 的情况下写入线程之间的通信。

如果我只在一个插槽中使用核心,那么写回缓存对我的吞吐量来说没问题,但对于两个插槽,我想知道是否有更快的东西,比如芯片网络或 Intel QuickPath 互连?

另外,有没有不用直接写汇编代码就可以利用这个特性的简单方法?

参考: https://software.intel.com/en-us/forums/intel-moderncode-for-parallel-architectures/topic/700477

TL:DR: 不,CPU 硬件已经针对一个核心存储和另一个核心加载进行了优化。没有神奇的高性能低延迟方法可以替代。如果写端可以以某种方式强制写回到 L3,那可以减少读端的延迟,但不幸的是没有好的方法来做到这一点(Tremont Atom 除外,见下文)。


共享末级缓存已经支持一致性流量,避免 write/re-read 进入 DRAM。

不要被 MESI 图所迷惑;那些显示没有共享缓存的单级缓存。

在真实的 CPU 中,来自一个内核的存储只需要写回最后一级缓存(现代 x86 中的 LLC = L3),以便来自其他内核的负载访问它们。 L3 可以容纳脏线;所有现代 x86 CPU 都具有回写 L3 而不是直写。

在现代多插槽系统上,每个插槽都有自己的内存控制器 (NUMA),因此侦听会检测何时需要通过插槽之间的互连进行缓存-> 缓存传输。但是,是的,将线程固定到同一个物理内核确实可以改善内核间/线程间延迟。 (与 AMD Zen 类似,4 核集群共享 LLC 块,集群内/跨集群对内核间延迟很重要,即使在单个插槽内也是如此,因为没有一个大型 LLC 跨所有内核共享。)

没有比这更好的了;一个内核上的负载一旦到达 L3 并发现该行在另一个内核的私有 L1d 或 L2 中被修改,就会生成一个共享请求。这就是延迟高于 L3 命中的原因:加载请求必须在它知道它不仅仅是 L3 命中之前获得 L3。但是英特尔使用其大型共享 inclusiv L3 缓存标签作为侦听过滤器,以跟踪芯片上的哪个内核可能对其进行了缓存。 (这在 Skylake-Xeon 中发生了变化;它的 L3 不再包含在内,甚至不包含标签,并且必须有一些单独的监听过滤器。)

另见


有趣的事实:在 Core 2 CPU 上,内核之间的流量确实和 中的 DRAM 一样慢,即使对于共享 L2 缓存的内核也是如此。

早期的 Core 2 Quad CPU 实际上是同一个封装中的两个双核芯片,没有 共享最后一级缓存。那可能更糟;如果 "glue" 逻辑甚至可以在不写回 DRAM 的情况下进行脏数据的缓存-> 缓存传输,那么一些 CPU 就没有共享的 LLC 和 IDK。

但那些日子早已过去; 现代多核和多插槽 CPU 已针对核心间流量进行了优化。


你真的不能在读取端做任何特别的事情来加快速度。

如果您在写入端有 cldemote,或以其他方式将数据逐出回 L3,则读取端可能只会获得 L3 命中。但那是

是另一个关于尝试让写端将缓存行驱逐回 L3 的问题,这个问题是通过冲突未命中。

clwb 可能会减少读取端延迟,但缺点是它 强制 一直回写到 DRAM,而不仅仅是 L3 . (还有 。希望 IceLake 会给我们一个 "real" clwb。)

是关于基本同一件事的另一个问题。