clflushopt
对于这个用例来说是一个糟糕的主意。在覆盖它们之前从缓存中逐出行与您想要的相反。如果它们在缓存中很热,则可以避免 RFO(为所有权而读取)。
如果您使用的是 NT 商店,他们将驱逐任何仍然很热的线路,因此不值得clflushopt
先花费周期。
如果不是这样,你保证最坏的情况完全是在自取其辱。有关写入内存以及 RFO 与无 RFO 存储的更多信息, 请参阅增强型 REP MOVSB for memcpy 。(例如rep movsb
,至少可以在 Intel 上进行无 RFO 存储,但仍将数据热留在缓存中。)请记住,L3 命中可以比进入 DRAM 更快地满足 RFO。
如果您要使用常规存储(将 RFO)写入缓冲区,您可能会prefetchw
在准备好实际写入之前将其置于 L1D 中的独占状态。
(Cache-Line Write Back (without evicting))可能clwb
在这里有用,但我认为prefetchw
如果不是更好的话,至少会一样好(尤其是在 AMD 上,MOESI 缓存一致性可以在缓存之间传输脏线,所以你可以在你的 L1D 中插入一条仍然脏的线,并且能够在不将旧数据发送到 DRAM 的情况下替换该数据。)
理想情况下,malloc
将为您提供在当前内核的 L1D 缓存中仍然很热的内存。如果你发现很多时候,你得到的缓冲区仍然很脏,并且在另一个内核上的 L1D 或 L2 中,然后查看具有每个线程池的 malloc 或某种类似 NUMA 的线程意识。
据我了解,在_mm_clflushopt()
我需要调用_mm_sfence()
以使其非临时存储对其他内核/处理器可见之后。
不,不要认为clflushopt
是商店。它不会使任何新数据全局可见,因此它不会与内存操作的全局排序交互。
sfence
使您的线程的后续存储等待直到刷新的数据一直刷新到 DRAM 或内存映射的非易失性存储。
如果您正在刷新由常规 DRAM 支持的行,您只需要sfence
在一个存储之前启动一个非连贯 DMA 操作,该操作将读取 DRAM 内容而不检查缓存。由于其他 CPU 内核总是通过缓存,因此对您来说没有sfence
用或没有必要。(即使clflushopt
一开始是个好主意。)
即使您谈论的是实际的 NT 商店,其他核心最终也会看到您的商店没有sfence
. 您只需要sfence
确保他们在看到一些后来的商店之前看到您的 NT 商店。我在使先前的内存存储对后续的内存加载可见中对此进行了解释
会发生不好的事情吗?
不,clflushopt
不会影响缓存一致性。它只是触发回写(和驱逐),而不需要稍后的存储/加载等待它。
您可以clflushopt
在不影响正确性的情况下分配内存并由另一个线程使用。