【发布时间】:2018-05-23 18:25:23
【问题描述】:
在现代 x86 CPU 上,硬件prefetching 是一项重要的技术,可在用户代码明确请求缓存线之前将它们带入缓存层次结构的各个级别。
基本思想是,当处理器检测到对顺序或跨步顺序1位置的一系列访问时,它会继续并在序列中获取更多内存位置,甚至在执行指令之前(可能)实际访问这些位置。
我的问题是预取序列的检测是基于 完整地址(用户代码请求的实际地址)还是 缓存行地址除去底部 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, ...)。
现代硬件上安装了哪个系统(如果有的话)?
注意: 还可以想象,答案不会基于每个访问,而仅基于预取器在缓存的某个级别中未命中的访问正在观察,但同样的问题仍然适用于过滤后的“未命中访问”流。
1Strided-sequential 仅表示它们之间具有相同 stride (delta) 的访问,即使该 delta 不是 1。例如,一系列对位置 100, 200, 300, ... 的访问次数可以被检测为跨步访问,步长为 100,原则上 CPU 将基于此模式进行获取(这意味着在预取模式中可能会“跳过”某些缓存行)。
2 这里假设一个 64 位缓存行。
【问题讨论】:
-
我不确定,但根据英特尔优化手册第 7.5.3 节中的图表,硬件预取器隐藏缓存未命中延迟的能力取决于以字节为单位的步幅(即地址) .如果它使用缓存地址,我想我们会在 64 字节的段内看到扁平线。不过不确定。
-
根据英特尔的优化手册(关于 SnB 的第 2.3.5.4 节),流媒体(在 L2 中)仅查看 L1D / L1I 请求的线路模式。但目前尚不清楚该措辞对 L1D 预取器的含义。我认为我记得读过一个缓存行中的一系列加载可以触发下一个缓存行的预取,这是对 DCU 流式预取器描述的一种可能解释,因为 “被触发通过升序访问最近加载的数据"。但是基于 IP 的预取器仍然可以在每个insn 的基础上检测向前 3 步/向后 2 步。
-
切向相关:the L2 stream prefetcher seem to be triggered by access, not by misses 这也是我最近在测试中看到的结果。
-
@PeterCordes re" 但是基于 IP 的预取器仍然可以在每个 insn 的基础上检测 3 步前进 / 2 步后退" 你是什么意思?你的意思是它像分支预测器一样有历史吗?或者它会以亚高速缓存线精度检测顺序? IP 预取器是唯一受到影响的是有意义的,因为基于解释here 它是唯一可以检测步幅的。另外我认为预取器(或至少其中一些)不获取完整地址,而只获取页面偏移量。
标签: performance x86 cpu-architecture