2017-09-01 61 views
0

在释放内存之前,我正在从CPU高速缓存中清除内存范围。理想情况下,我想放弃这些缓存行而不将它们保存到内存中。因为没有人会使用这些值,并且再次获得该存储器范围的人(在malloc()/new/_mm_malloc()等之后)将首先用新值填充存储器。由于this question suggests,目前似乎没有办法在x86_64上实现理想。如果我在_mm_clflushopt()之后不发出_mm_sfence()会发生什么(坏)?

所以我做_mm_clflushopt()。据我所知,在_mm_clflushopt()之后,我需要调用_mm_sfence()使其非核心/临时存储对其他核心/处理器可见。但在这个特定的情况下,我不需要它的商店。

所以,如果我不叫_mm_sfence(),可以坏事发生?例如。如果其他核心/处理器设法再次快速地分配内存范围,并开始用新数据填充内存范围,那么新的数据是否会被当前内核刷新的旧缓存并发地覆盖?

编辑:快速后续分配是不可能的,我只是描述这种情况下,因为我需要的程序是正确的也有。

+1

请问,什么是摆在首位驱逐缓存的目的是什么? –

+0

@PasserBy,让它尽快被下一步真正使用的数据占据。如果没有明确的驱逐它,CPU会将旧的(不再使用的)数据保留在缓存中,直到旧数据变得最近被使用(LRU)w.r.t.缓存中的其他数据。 –

+0

如果它是可证明的,在高速缓存中的内容不再需要,并驱逐其既有可能,并提供加速,那不是已经被列入优化? –

回答

1

clflushopt是该用例一个可怕的想法。在覆盖之前从缓存中逐出线条与您想要的相反。如果它们在缓存中很热,则可以避免使用RFO(读取所有权)。

如果您使用NT店,他们会驱逐仍然是热的所有行,以便它不值得花费的周期做clflushopt第一。

如果没有,你完全保证最坏的情况下搬起石头砸自己的脚。请参阅Enhanced REP MOVSB for memcpy了解更多关于写入存储器的信息,以及RFO与no-RFO存储器的关系。 (例如,rep movsb至少可以在英特尔上无RFO存储,但仍然会将数据留在缓存中)。并且请记住,L3命中可以比进入DRAM更快地满足RFO。

如果你要写定期存储缓冲器(将RFO),你可能会prefetchw它得到它变成唯一状态在L1D你准备好实际写入之前。

这有可能是clwb(高速缓存行回写(不驱逐))在这里很有用,但我认为prefetchw总是会至少这么好,如果没有更好的(特别是在AMD那里MOESI cache coherency可以转移脏所以你可以在你的L1D中得到一条仍然很脏的线路,并且能够在没有将旧数据发送到DRAM的情况下替换那些数据。)

理想情况下,malloc会给你记忆仍然很热当前内核的L1D缓存。如果你发现很多时候,你得到的仍然是肮脏的缓冲区,而在另一个核心上的L1D或L2上,然后查看带有每线程池的malloc或某种类似NUMA的线程感知。

我的理解,_mm_clflushopt()后,我需要调用_mm_sfence()使其非临时卖场看到其他核心/处理器。

不,不认为clflushopt的商店。它不会使全局可见的新数据,所以它不会与全局的内存操作顺序进行交互。

sfence使线程的后店等待刷新的数据是一路刷新到DRAM或存储器映射的非易失性存储。

如果您正在刷新由常规DRAM支持的行,那么在存储之前您只需要sfence即可启动非相干DMA操作,该操作将在不检查缓存的情况下读取DRAM内容。由于其他CPU内核总是通过高速缓存,sfence是不是对您有用或必要的。 (即使clflushopt是摆在首位是个好主意。)


即使你在谈论实际NT店,其他核心最终会看到你的店没有sfence。如果你需要确保他们看到你的NT商店才看到一些后来店只需sfence。我在Make previous memory stores visible to subsequent memory loads

可以解释这个吗?

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

你可以clflushopt内存分配,并在不影响正确性被另一个线程使用。

+0

我不期望别的东西能很快得到分配。这只是一个例子,我怀疑我的程序是正确的,所以我需要澄清在这种情况下会发生什么。 –

+1

@SergeRogatch:如果你“clflushopt”一些内存并立即释放它,可能有另一个线程可能从malloc中获取它,并将一些存储的数据刷新到内存中。 (但可能不是因为'free'可能需要使用'lock'ed操作来将内存添加到全局空闲列表中,这会成为'clflushopt'的障碍。)但是,即使可以,这也不会影响正确性。它存储的数据仍然存在。你可以'clflushopt'分配内存并在另一个线程中使用而不影响正确性。 –

相关问题