这篇论文提出的是 IPCP(Instruction Pointer Classifier-based spatial Prefetching)

  1. 把不同 IP 的访存行为分成几类,再给每一类配一个极小、针对性很强的预取子机制,重点关注 L1 DCache
  2. 子预取器同时触发时,采用固定优先级处理
  3. 把在 L1 学到的分类信息传给 L2,形成一个轻量级多级预取框架

Insight

应当重点关注 L1-D 预取

  • L1 观测到的是未被过滤的原始访存流,而且一旦 L1 预取命中,收益最大
  • L2 观测到的访存模式往往已经被 L1 hit 和 L1 预取干扰了

另一种思路是:在 L1 学 pattern,但把更多预取请求直接下发到 L2/LLC。这会导致 L1 的 PQ/MSHR 更快被打满,反而影响 L1 自身预取的及时性和覆盖率。

论文用实验说明:

  1. 把预取做到 L1,相比只做到 L2,平均还能多带来 6%–13% 的加速
  2. 把“学习”放在 L1、但只“填充”到 L2,也比真正的 L1 预取差 3%–7%,个别 trace 上差距甚至超过 73%

很多访问模式和 IP 强相关

作者观察到:很多访问模式其实和 instruction pointer(IP)强相关

不是所有访问都该交给一个通用空间预取器去“全局学”;更好的做法是,先判断“这个 IP 属于哪一类访问行为”,再用相应的子预取器处理。

基于这个想法,IPCP 把 IP 分成三类:

  • CS(Constant Stride):固定步长
  • CPLX(Complex Stride):复杂但仍有局部规律的步长序列
  • GS(Global Stream):多个 IP 共同构成的稠密全局流

再加一个兜底的 tentative next-line (NL)。论文把这些子机制称为一个 bouquet of prefetchers,也就是“花束式预取器”:每一朵花都很小,但组合起来覆盖面很广。

IP 适合用于对访存行为分类的原因:

每个 IP 往往有相对稳定、可识别的访存行为

  • 某些 IP 基本总是在做规则 stride 访问,适合最简单的 IP-stride;
  • 某些 IP 的 stride 是交替变化的,比如 1,2,1,2,1,2,简单 stride 就学不会;
  • 还有些程序整体呈现“稠密顺序访问”,但从单个 IP 看是碎片化的,只有从“全局区域流”的角度看才容易预取。

但不适合静态标注:因为这些 IP 行为是“unique and persistent”的,而且一个 IP 在不同阶段还可能切换类别,因此需要在线分类而不是静态标注

针对不同的访存模式设计简单的子预取器比复杂单体预取器效果更好

相比于“按全局 miss 流做一个大预取器”并不是唯一思路;而按 IP 做分类,然后让不同子预取器针对不同的特定的访存模式进行处理,能以更低复杂度得到高覆盖

单体复杂空间预取器的问题:

  • 很多先进空间预取器本来就是为 L2/LLC 设计的,不适合 L1 的访问特征;
  • L1 对硬件代价、端口、时延特别敏感;
  • Bingo/SMS 虽然可以做 L1,但硬件开销接近 100KB,对一个 L1-D 预取器来说太重了

结论:在 L1 场景里,需要用极小代价来处理大部分常见空间模式


IPCP 的整体架构

IPCP 本质上是一个 IP 分类器 + 一组极小预取器 + 协调机制 + 多级扩展机制

  1. 在 L1 上做 IP 分类,并根据分类结果发起预取;
  2. 把 L1 的分类信息通过少量元数据传给 L2,让 L2 可以沿着相同的“语义”继续更深地预取

IP 分类器

IP 分类 1: CS, Constant Stride

对应模式:一个 IP 连续访问的 cache-line 地址之间呈现固定 stride

比如: C0, C3, C6, C9...

设计结构:一个按 IP 索引、带 tag 的 IP table,记录:

  • 上一次访问的虚拟页号的低两位 last-vpage
  • 上一次访问的页内 cache line offset last-line-offset
  • 当前 stride
  • 一个 2-bit confidence

通过前后两次访问的页内 offset 和页号变化,可以计算 stride;连续看到相同 stride,就提升置信度;置信度足够高时,开始预取。

预取地址是:当前 cache-line 地址 + k × learned_stride (其中 k 表示 prefetch degree)

  1. IP Table 在这里使用 L1 用虚拟地址训练 (适用于 VIPT)
    • 如果 L1 是 PIPT,IPCP 仍能工作,但整体存储会增大到约 2KB
  2. 跨页时 stride 学习的问题:只存最近页号低两位,就够判断是前一页还是后一页

CS 类 IP 的特点:

  • 成本低
  • 能处理大量最常见的规则访问
  • 复杂访存模式用其他预取器处理

IP 分类 2: CPLX, Complex Stride

对应模式:非固定 stride,而是有规律变化的 stride 序列

比如:

  • 3,3,4,3,3,4
  • 1,2,1,2,1,2

设计结构: CSPT(Complex Stride Prediction Table)

  • 每个 IP 在 IP table 里记录一个 signature
  • 这个 signature 是过去若干 stride 的压缩表示
  • 用 signature 去索引 CSPT(Complex Stride Prediction Table)
  • CSPT 给出“下一次 stride”和其 confidence
  • 连续预测多个 stride,直到达到 degree

signature 更新公式是:signature = (signature << 1) XOR stride

CSPT 和 SPP 的区别:

  • SPP : 按页内全局 delta 历史建模 (global pattern)
  • CPLX : 按单个 IP 的局部 stride 序列建模(local per-IP access pattern)

CPLX 类 IP 的特点:

  • 优点:
    • 很适合 L1,因为 per-IP 状态小,查表快
    • 解决了传统 IP-stride 处理非固定 stride 的问题
    • 不必维护像 SPP 那样的大型 signalture table
  • 缺点:
    • 要多一步 CSPT 查表,在 L1 时延上比较敏感

论文因此专门讨论了 pipeline 和 lookahead 跳过前一项的实现方式?


IP 分类 3: GS, Global Stream

对应模式:内存访问整体上像连续流,但从单个 IP 角度看是零散的

比如:

  • IP C 访问 C0,C2,C1
  • IP D 访问 C3,C6,C4,C5
  • IP E 访问 C9,C8,C7

此时既不是 per-IP stride,也不是 per-IP complex stride,而是应该直接把整块区域当成“stream region”来预取

结构设计: RST(Region Stream Table)

  • region 大小是 2KB
  • 每个 region 维护一个 32-bit bit-vector,表示 32 个 cache line 哪些被访问过
  • 维护 dense-count,表示这个 region 里有多少唯一 cache line 被触达
  • 当一个 region 中访问比例超过阈值(论文设为 75%)时,视为 dense region
  • 所有访问过这个 dense region 的 IP 都会被标成 GS IP
  • 还会学习正向/反向方向,用来决定后续按哪一边连续预取

tentative 机制:
如果等新 region 自己训练成 dense,再开始预取,比较慢。因此利用“前一个 region 已经很密”这一事实,在新 region 一开始就假设它也会稠密,于是提前发起 GS 预取?

GS 的特点:

  • GS 通过“区域稠密性”大面积覆盖 region,提升 timeliness 和 coverage
  • 会牺牲一些 accuracy 换来的覆盖率和时序优势

备选预取器: Tentative NL 有节流的 NextLine Prefetch

当某个 IP 访问不属于 CS、GS、CPLX 三类时,IPCP 考虑 next-line 预取。但 L1 上乱发 NL 会污染 cache ,于是把它设计成 tentative NL

  • 按 core 统计 L1 MPKI;
  • 只有当 MPKI 低于阈值时,才允许 NL 开启;
  • 否则关闭。

Bouquet 多预取器管理

一个 IP 可能同时满足多个类别, 此时 IPCP 采用固定优先级:
GS > CS > CPLX > NL

实验证明,这个顺序性能最优。若改变优先级,性能会下降大约 9%;优先把更激进的 GS 放在最前,收益最好。

L1 中每类预取器都有自己的 issued/useful 计数器,按 epoch 统计准确率:

  • 高水位:0.75
  • 低水位:0.40

若某类预取 accuracy > 0.75,就逐渐提高 degree,直到默认 degree;
若 accuracy < 0.40,就逐步降到 degree=1。

默认 degree 为:

  • L1:CS=3,CPLX=3,GS=6
  • L2:CS=4(GS/NL 也可用,但 L2 不使用 CPLX)

多级 IPCP:L1 学习语义,L2 做更深预取

IPCP 的做法:

  • L1 做 IP 分类;
  • 发出 prefetch 时,把 class-type + stride/stream-direction 一起传给 L2
  • 总共只要 9 bit 元数据
  • L2 根据这些元数据在自己的 IP table 中记录对应类别,然后继续更深地预取

L2 中:

  • 不使用 CPLX;
  • 使用 CS / GS / NL;
  • 只有当 L1 某类 accuracy 超过 75% 时,才把该类 stride 信息传给 L2,以防 L2 错误学习

作者还说明,如果总线位宽紧张,不能传输完整 IP,也可以只传 IP-tag 和 IP-index,共约 15 bit,而不是 64-bit IP

但问题是:L1 向 L2 传元数据如果通过总线传,复杂度会上升不少,是否可以使用单独的总线?


L1 实现中存在的问题:

  1. L1 latency:
    • IPCP 的 L1 发起预取需要三拍:
      1. 查 IP table
      2. 根据优先级决定是否 GS / CS,同时可发起 CSPT 查表
      3. 如果需要,再根据 CSPT 或 NL 发预取
    • 作者在 7nm、4GHz 条件下做了 RTL 级综合验证,说明这个时序是可行的。若关键路径仍太紧,可以让 CPLX 在 lookahead 时直接跳过第一项,从第二项开始预取,以换取时序余量。
  2. L1 不能每次都 probe cache
    • L1-D 端口紧张,预取器若每次都去查 L1 以避免重复预取,端口竞争会加剧
    • 论文用一个 32-entry RR filter(recent-request filter) 记录最近 demand/pre-fetch 标签,预取前先查这个小过滤器,命中就放弃预取,避免额外 probe L1-D

IPCP 的硬件开销:

  • L1:740B
  • L2:155B
  • 总计:895B

实验结果

总体性能

  • memory-intensive SPEC CPU 2017 单核 workload,相对 no prefetch,平均提升 45.1%
  • 整个 SPEC CPU 2017 单核全集,平均提升 22%
  • 多核 mixes,平均提升 23.4%

IPCP:

  • L1/L2/L3 demand miss 覆盖率分别达到 0.60 / 0.79 / 0.83
  • L1 accuracy 为 0.80

在多级预取组合中,论文比较了:

  • SPP + Perceptron + DSPatch
  • MLOP
  • Bingo
  • TSKID
  • IPCP

前三强对整个 SPEC CPU 2017 单核全集的平均提升大概都在 42.5% 左右

元数据传输和 L2 协同的收益

ablation:

  • 只用 L1 bouquet,大概到 40%
  • 再加上 L2 元数据协同,可再多提高 5.1%
  • 如果不传 metadata,memory-intensive 应用性能平均会下降 3.1%

各类子预取器单独贡献

  • CSCPLX 单独使用时都能超过 30%
  • CS + CPLX 超过 34%
  • 加上 tentative NL 后到 36%
  • GS 单独并不强,性能提升不到 15%
  • GS 一旦加入 bouquet,整体可从 36% 提升到 40%
  • 再加 L2 协同到 45.1%

DRAM 带宽代价

  • IPCP 额外带宽开销大约 16.1%
  • 而 SPP+Perceptron+DSPatch 和 MLOP 约为 28%,TSKID 更高

Limits

本质上还是空间预取器,在 server workload 上表现有限

论文承认,CloudSuite 这类 server workload 上,空间预取器普遍表现有限,需要 temporal prefetcher 叠加

GS 的设计参数比较经验化, 可移植性、多架构稳定性还需要更多验证。

比如 region 大小 2KB、dense 阈值 75%、MPKI 阈值 50/40、accuracy 高低水位 0.75/0.40,这些参数的设计偏经验性。可移植性、多架构稳定性还需要更多验证。

效果依赖 IP 稳定性

IP 分类成立的前提是:

  • 同一 IP 的行为相对稳定
  • 或者至少在某一阶段稳定

一些共享库、多态、JIT、复杂分支路径下,同一 IP 的访问行为可能发生变化较大