为什么指针在双链表中追逐可以避免缓存抖动(自我驱逐)?

时间:2015-02-17 06:54:07

标签: c caching cpu cpu-architecture cpu-cache

我试图了解有关缓存时序问题的this paper

在3.6节中,作者解释了一种技术,它允许您填充连续的缓存区域并测量此填充过程的时间。他们提到:

“由于在现代CPU中实现了两个优化:内存访问的重新排序,以及内存的自动预读“硬件预取器”。我们的 攻击代码通过使用以下“指针追逐”技术解决这两个中断。在初始化期间,攻击者的内存被组织成链表(可选地,随机置换);之后,通过遍历此列表来完成启动和探测(参见图7)。为了最大限度地减少缓存抖动(自我驱逐),我们使用双向链表并将其向前遍历以进行启动但向后遍历以进行探测。此外,为了避免“污染”其自己的样本,探针代码将每个获得的样本存储到它刚刚完成测量的相同缓存集中。在某些平台上,人们可以通过使用写入而不是读取来改善时序差距,或者使用W读取。“

我对这一段有疑问:

链接列表如何避免因硬件预取和重新排序而导致的时序变化?

1 个答案:

答案 0 :(得分:2)

当前实现的硬件预取程序仅处理固定的步幅访问模式,因此关于存储器地址任意排序的访问不被识别为可预取的。这样的硬件预取程序仍然可以检测和使用意外的步幅模式。例如,如果地址[X + 5] =地址[X] + N和地址[x + 7] =地址[x + 5] + 2N(请注意,地址不必以常数访问计数分隔),预取器可以预测N的步幅。这可能会适度减少明显的未命中延迟(一些预取有效)或引入一些缓存污染。

(如果检测到的/预测的N很小并且链接列表包含在相对于高速缓存大小的内存的适度区域内(因此大多数步幅预取将是将要使用的地址很快),基于步幅预取可能会产生明显的积极影响。)

通过使用数据相关的访问(遍历链接需要访问数据),可以防止访问重新排序。在上一个节点的下一个指针可用之前,硬件无法加载下一个节点。

有一些学术建议支持预取这些模式甚至是一般的相关性(例如,见this Google Scholar search for Markov prefetching),但尚未(据我所知)已在商业硬件中实现。

作为旁注,通过从启动访问以相反的顺序遍历探测访问,对于常见的,面向LRU的替换,避免了过多的未命中。