PREFETCH和PREFETCHNTA指令之间的区别

Abh*_*kam 6 x86 assembly caching prefetch isa

PREFETCHNTA指令基本上用于通过预取器将数据从主存储器带到缓存,但是NT已知带有后缀的指令会跳过缓存并避免缓存污染。

那么PREFETCHNTA,与PREFETCH指令有何不同?

Pet*_*des 10

prefetchNTA 不能绕过缓存,只能减少(不能避免)污染。它不能破坏缓存一致性或违反 WB(回写)内存区域的内存排序语义。(与 NT 存储不同,NT 存储完全绕过缓存并且即使在正常的 WB 内存上也是弱排序的。)

在纸面上,x86 ISA 没有指定它如何实现 NT 提示。 http://felixcloutier.com/x86/PREFETCHh.html说:“ NTA(关于所有缓存级别的非临时数据)——将数据预取到非临时缓存结构和靠近处理器的位置,最大限度地减少缓存污染. ” 任何特定的 CPU 微架构选择如何实现完全取决于架构师。


prefetchNTA从英特尔 CPU 上的WB 内存1正常填充 L1d,允许以后的负载正常加载到 L1d(只要预取距离足够大以完成预取,并且足够小以至于在需求加载之前不会再次被逐出)。正确的预取距离取决于系统和其他因素,并且可能相当脆弱。

它在 Intel CPU 上所做的是跳过非包含外部缓存。因此,在 Skylake-AVX512 之前的 Intel 上,它绕过 L2 并填充 L1d + L3。但在 SKX 上,它也完全跳过 L3 缓存,因为它更小且不包含。请参阅 当前的 x86 架构是否支持非临时加载(来自“正常”内存)?

在具有包容性 L3 缓存(它无法绕过)的 Intel CPU 上,它通过限制预取到关联包容性 L3 缓存的一种“方式”来减少 L3 污染。(这通常类似于 16 路关联,因此可以污染的总容量prefetchnta仅为 L3 总大小的约 1/16)。


@HadiBrais 评论了这个答案,并提供了一些关于 AMD CPU 的信息。

显然 AMD 并没有通过仅获取缓存的一种方式来限制污染,而是使用“快速驱逐”标记分配使用 NT 预取获取的行。可能这意味着在 LRU 位置而不是最近使用的位置进行分配。因此,该缓存集中的下一个分配将驱逐该行。


脚注 1: prefetchNTA我认为从 WC 内存预取到LFB(行填充缓冲区),允许 SSE4.1movntdqa加载命中已经填充的 LFB。(根据英特尔的说法,movntdqa从 WC 内存加载通过将数据拉入 LFB来工作。这就是movntdqa同一“缓存线”上的多个加载可以避免多个实际 DRAM 读取或 PCIe 事务的方式)。另请参阅非临时加载和硬件预取器,它们是否协同工作?- 不,不是硬件预取。

但请注意,movntdqa从 WB 内存是没有用的。它就像一个普通的负载(由于某种原因加上一个 ALU uop)。

  • 根据 AMD 17h 系列优化手册第 2.6.4 节,“prefetchnta”通过快速逐出标记来获取 L2 中的行。但较旧的 AMD 处理器(如某些较旧的英特尔处理器)会进入 L1。 (3认同)
  • @Noah:有几种方法,但可能对整体性能没有用。(但可能是为微基准创建条件,如[将代码放入 L1 指令缓存而不执行](/sf/ask/3399988441/) - 请参阅我的 2 个答案)。[如何预取不常用的代码?](/sf/ask/1135313021/) 的答案最多只能将代码放入二级缓存。(并准备 dTLB,而不是 iTLB。) (3认同)
  • ...缓存到缓存或主内存延迟(英特尔内存延迟检查器工具可用于测量这些延迟)。如果它接近 L3 延迟,则该线将在 L3 中填充。如果它接近 C2C 延迟或主内存延迟,则该线路不在 L3 中。该测试将使我们能够最终确定该线是否填充到 L3 和/或 L1 中。 (2认同)