【发布时间】:2015-11-13 06:04:05
【问题描述】:
当从连续的内存位置执行一系列 _mm_stream_load_si128() 调用 (MOVNTDQA) 时,硬件预取器是否仍会启动,或者我应该使用显式软件预取(带有 NTA 提示)以获得在避免缓存污染的同时预取的好处?
我之所以这么问是因为他们的目标在我看来是矛盾的。流式加载将绕过缓存获取数据,而预取器尝试主动将数据获取到缓存中。
当顺序迭代大型数据结构时(处理过的数据不会在很长一段时间内被修改),避免污染 chache 层次结构对我来说是有意义的,但我不想招致频繁的 ~100 循环惩罚因为预取器处于空闲状态。
目标架构是英特尔 SandyBridge
【问题讨论】:
-
好问题。有一个
prefetchnta,但我忘记了我读到的关于这个案例的内容。 -
根据一些较早的英特尔文档,非临时加载与正常对齐加载相同,除非内存不可缓存。我的个人经验已经证实它们对正常数据没有性能差异。但这又回到了 Nehalem/Sandy Bridge 时代。我不知道 Haswell 或 Skylake 是否有任何变化。
-
@PeterCordes
prefetchnta仅拉入 L1 缓存而不是所有缓存。也就是说,我不知道它如何与硬件预取器交互。在内存访问“足够随机”以致硬件预取器失败但“足够顺序”以使用完整缓存线的情况下(就像许多缓存阻塞优化的情况一样),我发现软件预取使得在没有超线程的情况下存在巨大差异。 (~10%) 但我发现prefetcht0和prefetchnta之间没有明显的区别。 -
@Mysticial:L3 包含在最近的 Intel 设计中,因此 L3 标签可用于缓存一致性检查。如果另一个内核修改了该缓存行,则存在于 L1 而非 L3 的缓存行可能会过时,但我认为 IA32 的缓存一致性模型不允许这样做(因此不能以这种方式实现)。
prefetchnta是在 PIII 时代引入的,在多核 CPU 之前。如果它在当前设计上与prefetch0完全相同,我一点也不感到惊讶,例如lddqu现在与movdqu完全相同。也许prefetchnta使缓存行更有可能再次被快速驱逐。 -
@PeterCordes 感谢您对缓存的洞察。我从来没有从缓存一致性的角度考虑过这个。
标签: performance x86 sse cpu-cache prefetch