C++ 如果我不';是否在clflushopt()之后发布?

C++ 如果我不';是否在clflushopt()之后发布?,c++,concurrency,x86-64,cpu-cache,memory-fences,C++,Concurrency,X86 64,Cpu Cache,Memory Fences,在释放内存之前,我正在从CPU缓存中逐出内存范围。理想情况下,我希望放弃这些缓存线,而不将它们保存到内存中。因为没有人会使用这些值,无论谁再次获得该内存范围(在malloc()/new/\um\u malloc()等之后),都将首先用新值填充内存。因此,目前似乎没有办法在x86_64上实现理想 因此,我正在做\u mm\u clflushopt()。据我所知,在\u-mm\u-clflushopt()之后,我需要调用\u-mm\u-sfence(),以使其非临时存储对其他内核/处理器可见。但在这

在释放内存之前,我正在从CPU缓存中逐出内存范围。理想情况下,我希望放弃这些缓存线,而不将它们保存到内存中。因为没有人会使用这些值,无论谁再次获得该内存范围(在
malloc()
/
new
/
\um\u malloc()
等之后),都将首先用新值填充内存。因此,目前似乎没有办法在x86_64上实现理想

因此,我正在做
\u mm\u clflushopt()
。据我所知,在
\u-mm\u-clflushopt()
之后,我需要调用
\u-mm\u-sfence()
,以使其非临时存储对其他内核/处理器可见。但在这种情况下,我不需要它的商店

所以,如果我不调用
\u mm\u sfence()
,会发生什么坏事吗?例如,如果某个其他内核/处理器能够足够快地再次分配该内存范围,并开始用新数据填充该内存范围,那么新数据是否会被当前内核刷新的旧缓存同时覆盖


编辑:快速的后续分配是不可能的,我只是描述这个案例,因为我需要程序在那里也是正确的。

clflushopt
对于这个用例来说是个糟糕的主意。在覆盖行之前从缓存中逐出行与您想要的相反。如果它们在缓存中是热的,则可以避免RFO(读取所有权)

如果您使用的是NT商店,它们会逐出所有仍然热门的行,因此不值得先花时间做
clflushopt

如果不是这样,你保证在最坏的情况下,这完全是自食其果。有关写入内存、RFO与无RFO存储的更多信息,请参阅。(例如,
rep movsb
至少不能在英特尔上进行RFO存储,但仍能使数据在缓存中保持热状态。)请记住,三级命中可以比去DRAM更快地满足RFO

如果您将要使用常规存储写入缓冲区(这将是RFO),您可以在准备实际写入之前,在其上预取
prefetchw
,使其在L1D中处于独占状态

在这里,
clwb
(缓存线写回(无逐出))可能会很有用,但我认为
prefetchw
即使不是更好,也至少会和它一样好(特别是在AMD上,它可以在缓存之间传输脏线,这样您就可以在L1D中获得一条仍然脏的线,并且能够在不将旧数据发送到DRAM的情况下替换该数据。)

理想情况下,
malloc
将为您提供当前内核的L1D缓存中仍然很热的内存。如果您发现很多时候,另一个内核上的L1D或L2中的缓冲区仍然很脏,那么查看具有每线程池或类似NUMA的线程感知的malloc。

据我所知,在
\u-mm\u-clflushopt()
之后,我需要调用
\u-mm\u-sfence()
,以使其非临时存储对其他内核/处理器可见

不,不要将
clflushopt
视为一个存储。它不会使任何新数据全局可见,因此不会与内存操作的全局顺序交互

sfence
使线程的后续存储等待,直到刷新的数据一直刷新到DRAM或内存映射的非易失性存储

如果您正在刷新由常规DRAM支持的线路,则只需在启动非一致DMA操作的存储之前执行
sfence
,该操作将在不检查缓存的情况下读取DRAM内容。由于其他CPU内核总是通过缓存,因此
sfence
对您没有用处或必要。(即使
clflushopt
最初是个好主意。)


即使你说的是实际的NT商店,其他核心最终也会看到你的商店没有
sfence
。如果你需要确保他们在看到以后的商店之前看到你的NT商店,你只需要
sfence
。我在

会发生什么坏事吗

不,
clflushopt
不会影响缓存一致性。它只会触发写回(&逐出),而不会在以后进行存储/加载以等待它


您可以
clflushopt
由另一个线程分配和使用的内存,而不影响正确性。

我可以问一下,首先删除缓存的目的是什么吗?@passway,让它尽快被下一个真正使用的数据占用。如果不显式地删除它,CPU将保留旧的(不再使用)缓存中的数据,直到旧数据成为最近最少使用的数据(LRU)w.r.t.缓存中的其他数据。如果可以证明缓存中的内容不再需要,并且逐出它是可能的,并且提供了一个加速,那么这不会已经包含在优化器中吗?@路人,也许这太难证明了,所以优化器不会走那么远。简化,这取决于具体情况:有时你会我很快会在同一地址范围内进行分配,有时您不希望分配任何内容。因此程序员更容易根据具体情况进行决定。但我们可以提交GCC/Clang的提案:)我不希望其他东西很快被分配。这只是一个我怀疑我的程序是否正确的例子,所以我需要澄清在这种情况下会发生什么。@SergeRogatch:如果你
clflushopt
立即释放一些内存,另一个线程可能会从malloc获取它并存储一些数据o内存。(但可能不是因为
free
可能需要使用
lock
ed操作将内存添加到全局可用列表,这将成为
clflushopt
的障碍)但即使可以,也不会影响正确性。它存储的数据仍然存在。您可以
clflushopt
另一个threa分配和使用的内存