我想将线程ping通到两个CPU插槽中的所有内核,并在线程之间写入通信,而无需写回DRAM。

如果仅在一个插槽中使用内核,则写回高速缓存对于我的吞吐量就可以了,但是对于两个插槽,我想知道是否有更快的速度,例如片上网络或Intel QuickPath Interconnect?

而且,有什么简便的方法可以利用这种功能而无需直接编写汇编代码?

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

最佳答案

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

共享的最后一级缓存已经支持了一致性流量,从而避免了对DRAM的写入/重新读取。

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

在实际的CPU中,一个核心的存储只需要写回到最后一级的高速缓存(现代x86中为LC = L3),其他核心的负载就可以访问它们。 L3可以容纳脏线;所有现代x86 CPU都具有不写回的L3。

在现代的多套接字系统上,每个套接字都有其自己的内存 Controller (NUMA),因此监听可检测何时需要在套接字之间的互连上进行cache-> cache传输。但是可以,将线程固定到相同的物理内核确实可以改善内核间/线程间的延迟。 (对于AMD Zen,类似地,四个内核的群集共享一个LLC块,即使在单个套接字内,群集内/群集间的内核间延迟也很重要,因为所有内核之间没有共享一个大的LLC。)

你不能做得比这更好。一旦一个核心上的负载到达L3,并在另一核心的私有(private)L1d或L2中发现线路已修改,就会生成共享请求。这就是为什么延迟时间比L3命中率高的原因:加载请求必须获得L3才能知道它不仅仅是L3命中。但是英特尔将其大型共享的inclusiv L3缓存标签用作探听过滤器,以跟踪芯片上可能缓存了哪个内核。 (在Skylake-Xeon中已更改;它的L3不再包含在内,甚至不包含标签,并且必须具有一些单独的探听过滤器。)

另请参阅Which cache mapping technique is used in intel core i7 processor?

有趣的事实:在Core 2 CPU上,即使对于共享L2高速缓存的内核,内核之间的流量实际上也像some cases中的DRAM一样慢。

早期的Core 2 Quad CPU实际上是同一封装中的两个双核芯片,并且不共享最后一级的缓存。情况可能更糟。如果“胶水”逻辑甚至可以在不回写至DRAM的情况下进行高速缓存->高速缓存传输脏数据,则像这样的某些CPU没有共享的LLC和IDK。

但是那些日子已经过去了。 现代多核和多路CPU在内核间通信方面已尽可能优化。

在读取方面,您真的无法做任何特殊的事情来加快处理速度。

如果您在写端使用cldemote或通过其他方式将数据逐出到L3,则读端可能只会获得L3命中。但这是only available on Tremont Atom

x86 MESI invalidate cache line latency issue是另一个有关尝试使写端将高速缓存行逐出L3的问题,这是由于冲突未命中而引起的。
clwb可能可以减少读取侧延迟,但是缺点是它会强制将回写方式一直写入DRAM,而不仅仅是L3。 (在Skylake-Xeon it does evict, like clflushopt 上。希望IceLake会给我们一个“真实的” clwb。)

How to force cpu core to flush store buffer in c?是关于同一件事的另一个问题。

关于assembly - 有什么方法可以为Intel CPU直接核心到核心通信代码编写代码?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58741806/

10-11 16:32