PREFETCH 和 PREFETCHNTA 指令之间的区别
Difference between PREFETCH and PREFETCHNTA instructions
PREFETCHNTA
指令基本上用于通过预取器将数据从主内存带到缓存,但是带有 NT
后缀的指令可以跳过缓存并避免缓存污染。
那么PREFETCHNTA
与PREFETCH
指令有什么不同呢?
prefetchNTA 不能绕过缓存,只能减少(不是避免)污染。它不能破坏缓存一致性或违反 WB(回写)内存区域的内存排序语义。 (不像 NT 存储,它完全绕过缓存并且即使在普通 WB 内存上也是弱排序的。)
理论上,x86 ISA 没有指定如何它实现 NT 提示。
http://felixcloutier.com/x86/PREFETCHh.html 说:“NTA(与所有缓存级别相关的非时态数据)——将数据预取到非时态缓存结构中并靠近处理器的位置,从而最大限度地减少缓存污染。" 任何特定的 CPU 微架构如何选择实现完全取决于架构师。
prefetchNTA
from WB memory1 on Intel CPUs 正常填充 L1d,允许稍后加载正常命中 L1d(只要预取distance 足够大以便预取完成,并且足够小以至于它不会在需求负载之前再次被驱逐)。正确的预取距离取决于系统和其他因素,并且可能相当脆弱。
它在 Intel CPUs 上的作用是跳过非包容性外部缓存。因此在 Skylake-AVX512 之前的 Intel 上,它绕过 L2 并填充 L1d + L3。但在 SKX 上,它也完全跳过了 L3 缓存,因为它更小且不包含在内。看
Do current x86 architectures support non-temporal loads (from "normal" memory)?
在 Intel CPU 具有包容性 L3 缓存(无法绕过)的 Intel CPU 上,它通过限制为预取到关联的包容性 L3 缓存的一种“方式”来减少 L3 污染。 (这通常类似于 16 向关联,因此 prefetchnta
可以污染的总容量仅为总 L3 大小的 ~1/16)。
@HadiBrais 评论了这个答案并提供了一些关于 AMD CPUs 的信息。
显然,AMD 不是通过仅通过高速缓存的一种方式获取来限制污染,而是分配带有“快速驱逐”标记的 NT 预取获取的行。可能这意味着分配在 LRU 位置而不是最近使用的位置。因此,该组缓存中的下一次分配将逐出该行。
脚注 1:prefetchNTA
从 WC 内存中预取到 , allowing SSE4.1 movntdqa
loads to hit an already-populated LFB. (movntdqa
loads from WC memory , according to Intel. That's how multiple movntdqa
loads on the same "cache line" can avoid multiple actual DRAM reads or PCIe transactions). See also Non-temporal loads and the hardware prefetcher, do they work together? - 不,不是 HW 预取。
但请注意,WB 内存中的 movntdqa
没有用。它就像普通负载一样工作(出于某种原因加上一个 ALU uop)。
PREFETCHNTA
指令基本上用于通过预取器将数据从主内存带到缓存,但是带有 NT
后缀的指令可以跳过缓存并避免缓存污染。
那么PREFETCHNTA
与PREFETCH
指令有什么不同呢?
prefetchNTA 不能绕过缓存,只能减少(不是避免)污染。它不能破坏缓存一致性或违反 WB(回写)内存区域的内存排序语义。 (不像 NT 存储,它完全绕过缓存并且即使在普通 WB 内存上也是弱排序的。)
理论上,x86 ISA 没有指定如何它实现 NT 提示。 http://felixcloutier.com/x86/PREFETCHh.html 说:“NTA(与所有缓存级别相关的非时态数据)——将数据预取到非时态缓存结构中并靠近处理器的位置,从而最大限度地减少缓存污染。" 任何特定的 CPU 微架构如何选择实现完全取决于架构师。
prefetchNTA
from WB memory1 on Intel CPUs 正常填充 L1d,允许稍后加载正常命中 L1d(只要预取distance 足够大以便预取完成,并且足够小以至于它不会在需求负载之前再次被驱逐)。正确的预取距离取决于系统和其他因素,并且可能相当脆弱。
它在 Intel CPUs 上的作用是跳过非包容性外部缓存。因此在 Skylake-AVX512 之前的 Intel 上,它绕过 L2 并填充 L1d + L3。但在 SKX 上,它也完全跳过了 L3 缓存,因为它更小且不包含在内。看 Do current x86 architectures support non-temporal loads (from "normal" memory)?
在 Intel CPU 具有包容性 L3 缓存(无法绕过)的 Intel CPU 上,它通过限制为预取到关联的包容性 L3 缓存的一种“方式”来减少 L3 污染。 (这通常类似于 16 向关联,因此 prefetchnta
可以污染的总容量仅为总 L3 大小的 ~1/16)。
@HadiBrais 评论了这个答案并提供了一些关于 AMD CPUs 的信息。
显然,AMD 不是通过仅通过高速缓存的一种方式获取来限制污染,而是分配带有“快速驱逐”标记的 NT 预取获取的行。可能这意味着分配在 LRU 位置而不是最近使用的位置。因此,该组缓存中的下一次分配将逐出该行。
脚注 1:prefetchNTA
从 WC 内存中预取到 movntdqa
loads to hit an already-populated LFB. (movntdqa
loads from WC memory movntdqa
loads on the same "cache line" can avoid multiple actual DRAM reads or PCIe transactions). See also Non-temporal loads and the hardware prefetcher, do they work together? - 不,不是 HW 预取。
但请注意,WB 内存中的 movntdqa
没有用。它就像普通负载一样工作(出于某种原因加上一个 ALU uop)。