在现代x86 CPU上,硬件prefetching是一项重要技术,可以在用户代码明确请求高速缓存行之前将其放入高速缓存层次结构的各个级别。
基本思想是,当处理器检测到对顺序位置或跨步顺序位置的一系列访问时,即使在执行(可能)实际访问这些位置的指令之前,处理器也会继续执行操作并获取该顺序中的其他存储位置。
我的问题是,预取序列的检测是基于完整地址(用户代码请求的实际地址)还是基于缓存行地址,这几乎是除去底部6位2之外的地址。
例如,在具有64位高速缓存行的系统上,对完整地址1, 2, 3, 65, 150
的访问将对高速缓存行0, 0, 0, 1, 2
进行访问。
当在高速缓存行寻址中比常规寻址更规则的一系列访问时,这种差异可能是相关的。例如,一系列完整的地址,例如:
32, 24, 8, 0, 64 + 32, 64 + 24, 64 + 8, 64 + 0, ..., N*64 + 32, N*64 + 24, N*64 + 8, N*64 + 0
在完整地址级别上可能看起来像是跨步序列(实际上可能会错误地触发向后预取器,因为4次访问的每个子序列看起来像是8字节跨步反向序列),但是在高速缓存行级别上,它看起来像是向前一次缓存行(就像简单的序列
0, 8, 16, 24, ...
一样)。现代硬件上安装了哪个系统(如果有)?
注意:也可以想象答案不会基于每次访问,而是仅在预取程序正在观察的高速缓存的某些级别中丢失的访问,但是同样的问题仍然适用于过滤后的“错过访问权限”。
1Streded-sequential只是意味着它们之间具有相同跨度(增量)的访问,即使该增量不是1。例如,可以将对位置
100, 200, 300, ...
的一系列访问检测为跨度为100的跨步访问,并且原则上,CPU将基于此模式进行获取(这意味着某些高速缓存行可能会在“预取”模式中“跳过”)。2这里假设有一个64位的高速缓存行。
最佳答案
高速缓存行偏移量可能很有用,但如您的示例所示,它们也可能会产生误导。我将基于我在Haswell上的实验,讨论行偏移如何影响现代Intel处理器上的数据预取器。
我遵循的方法很简单。首先,我禁用除要测试的数据预取器之外的所有数据预取器。其次,我设计了一系列具有特定兴趣模式的访问。目标预取器将看到此序列并从中学习。然后,我接着访问特定的行,以通过准确地测量等待时间来确定预取器是否已预取该行。该循环不包含任何其他负载。它包含一个用于将延迟测量值存储在某个缓冲区中的存储。
有4个硬件数据预取器。 DCU预取器和L2相邻行预取器的行为不受行偏移模式的影响,而仅受64字节对齐地址的模式的影响。
我的实验没有显示任何证据表明L2流预取器甚至收到了缓存行偏移量。似乎它只获取行对齐的地址。例如,通过多次访问同一行,偏移模式本身似乎不会对预取器的行为产生影响。
DCU IP预取器显示了有趣的行为。我已经测试了两种情况:
关于performance - 是由精确地址流还是由高速缓存行流触发预取?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47732454/