Alecto (HPCA 2025): Integrating Prefetcher Selection with Dynamic Request Allocation Improves Prefetching Efficiency
下面我对 《》 做一版尽量系统、深入的解读。这篇论文提出的就是 Alecto,核心思想不是只在“输出端”控制哪些 prefetch 发出去,而是更进一步,在“输入端”就决定哪些 demand request 应该送给哪些 prefetcher 去训练。这也是它和 DOL、IPCP、Bandit 最本质的区别。论文来源:
1. 一句话概括这篇论文在做什么
这篇论文的核心命题是:
多预取器系统性能不好,往往不只是因为“发了太多错的 prefetch”,更因为“错误的 demand request 把本不该训练的 prefetcher 也训练坏了”。
因此,Alecto 的关键创新不是单纯调节 prefetch degree 或开关某个 prefetcher,而是提出:
- 按 PC 粒度识别“这个 load 指令适合由哪些 prefetcher 处理”;
- 只把 demand request 分配给这些“合适的 prefetcher”;
- 同时根据运行时表现,动态调整这些 prefetcher 的激进度。
换句话说,Alecto 认为:
- 以前很多工作在做“prefetcher output selection”;
- 它要做的是“prefetcher input allocation + selection 一体化”。
2. 论文的研究背景:为什么多预取器管理这么难
现代处理器往往不会只放一个 prefetcher,而是把 stream、stride、spatial、temporal 等多种 prefetcher 组合起来。原因很简单:单一 prefetcher 很难覆盖所有访存模式。但一旦多预取器并存,就会出现几个典型问题:
2.1 预取器之间会争资源
多个 prefetcher 会共享:
- 自己内部的 metadata / table
- prefetch queue
- cache 空间
- DRAM 带宽
如果多个 prefetcher 同时被相同的 demand stream 训练,它们可能会:
- 学到重复信息
- 发出重复 prefetch
- 挤占彼此的表项
- 进一步拉低准确率和 timeliness
2.2 现有方案大多只管“输出”,不管“输入”
论文把已有方案分成三类:
DOL
DOL 在“分配阶段”静态地串行尝试多个 prefetcher,但它的优先级是设计期固定的,所以不够灵活;而且 request 在传递过程中仍可能在前面不合适的 prefetcher 里留下训练痕迹。
IPCP
IPCP 更偏向在“prefetch 输出阶段”做静态优先级仲裁。所有 prefetcher 看到的是同一份 demand stream,因此每个 demand request 都会更新多个 prefetcher 的表,带来无谓训练和表冲突。
RL/Bandit 类
Bandit 这类 RL 方案会动态调整 prefetcher 的 degree 或 on/off,但它仍然默认所有 demand request 都喂给所有 prefetcher,没有解决“错误训练”的源头问题;同时,RL 方法要做更细粒度的识别,存储和动作空间会快速膨胀。
3. 论文指出的两个关键 limitation
这是全文最重要的动机部分。
3.1 Limitation 1:输入 demand request 分配不准确
作者认为,以前的预取器管理几乎都忽略了一个问题:
并不是每个 demand request 都应该训练所有 prefetcher。
如果一个本来适合 spatial pattern 的 request 被送去训练 stride prefetcher 或 temporal prefetcher,那么它可能:
- 占掉这些 prefetcher 的表项
- 替换掉原来有价值的 metadata
- 诱导它们发出无效或重复的 prefetch
论文展示了,在相同 composite prefetcher 下,引入动态 demand request allocation 后,prefetcher table miss 显著下降,说明很多表项冲突本来就是错误训练造成的。
这是 Alecto 最有价值的洞察:
训练路径本身就是可控资源,不该被当作“免费广播”。
3.2 Limitation 2:现有 selection criterion 太粗粒度
以前很多方案对所有 demand request 采用同一套规则:
- 某 prefetcher 全局更准,就总是优先它
- 某 degree 全局收益高,就总开更大 degree
问题是,同一程序内不同 PC 的行为可能完全不同。论文举例说明:某些 interleaving pattern 下,一个 PC 更适合 spatial prefetcher,另一个 PC 更适合 stride prefetcher;如果只用全局规则,就会把一部分 request 分错对象。
所以作者要把粒度下沉到 PC 粒度:
不同 load instruction,对应不同合适的 prefetcher 集合。
4. Alecto 的核心思想
Alecto 的总思路可以概括成一句话:
用每个 PC 历史上对各个 prefetcher 的局部表现,来决定未来这个 PC 的 demand request 应该喂给谁。
论文把 Alecto 分成三个主要硬件结构:
- Allocation Table
- Sample Table
- Sandbox Table
这三个结构配合起来,形成一个闭环:
- demand request 到来
- Allocation Table 决定送给哪些 prefetcher
- prefetcher 发出请求
- Sandbox / Sample 记录这些请求是否有效
- 周期性把统计结果反馈给 Allocation Table
- Allocation Table 更新各 prefetcher 在该 PC 下的状态
这本质上是一个 PC-local, feedback-driven scheduler。
5. 三个核心结构分别做什么
5.1 Allocation Table:决策中枢
Allocation Table 以 PC 为索引,为每个 PC 保存“每个 prefetcher 当前处于什么状态”。这些状态反映该 prefetcher 对这个 PC 的适配性。
它的任务有两个:
- 识别 suitable / unsuitable prefetcher
- 根据状态生成 identifier,把 demand request 动态路由给对应 prefetcher
这是 Alecto 最核心的结构。
5.2 Sample Table:统计每个 PC 上各个 prefetcher 的表现
Sample Table 也是按 PC 组织,记录:
- 每个 prefetcher 对该 PC 发了多少 prefetch(IssuedByPx)
- 其中多少后来被 demand 命中确认(ConfirmedPx)
- Demand Counter
- Dead Counter
这些统计用来估算 per-PC、per-prefetcher 的准确率,并驱动状态更新。
5.3 Sandbox Table:既是“命中确认器”,又是“重复过滤器”
Sandbox Table 有两个用途:
用途 1:判断过去发的 prefetch 是否有用
它记录最近发出的 prefetch 地址以及相关 PC 信息。当 demand request 到来时,如果地址命中 Sandbox Table,且 PC 信息匹配,说明此前的 prefetch 是“被确认的 useful prefetch”,于是增加 Sample Table 中对应 prefetcher 的 confirmed 计数。
用途 2:过滤 duplicate prefetch
在真正把 prefetch request 放进 prefetch queue 前,先查 Sandbox Table;如果命中,就直接丢弃,避免重复 prefetch。
这很关键,因为 Alecto 允许多个 prefetcher 处于 IA 态并同时工作,所以必须有一个统一的末端过滤器,来避免“多个好 prefetcher 都发到同一个地址”。
6. Alecto 最关键的设计:状态机
Alecto 为 每个 PC 上的每个 prefetcher 设置三类状态:
- UI (Un-Identified):尚未判断是否适合
- IA (Identified and Aggressive):适合,且允许逐步提高 aggressiveness
- IB (Identified and Blocked):不适合,暂时阻塞
其中:
- IA 有多个子状态:IA0 到 IAM
- IB 有多个子状态:IB−N 到 IB0
这使得 Alecto 既能表达“适合/不适合”,又能表达“适合到什么程度”“需要阻塞多久”。
6.1 UI:观察期
新 PC 进入 Allocation Table 后,所有 prefetcher 初始都是 UI。
UI 的含义不是“可用”,而是“先给少量机会试训”。
在 UI 状态下,Alecto 仍会给该 prefetcher 分配 demand request,但 prefetch degree 只给一个保守值,比如 2。
6.2 IA:已确认适合
如果某 prefetcher 在该 PC 上表现好,它会进入 IA。
IA 的子状态越高,表示 degree 越大。Alecto 认为:
- 准确率足够高 → 可以更激进
- 更激进可能提升 coverage 和 timeliness
所以它允许在 IA_m 中逐步升降级,而不是一次性开满。
6.3 IB:已确认不适合
如果一个 prefetcher 在某个 PC 上表现很差,它会被送到 IB,停止接收 demand request。
但它不是永久淘汰,而是“冷却一段时间后重试”。
这解决了访存模式变化的问题:今天不合适,不代表之后永远不合适。
7. 状态转移规则怎么理解
论文引入两个阈值:
- PB (Proficiency Boundary):优秀阈值
- DB (Deficiency Boundary):糟糕阈值
利用这两个阈值,状态机发生四种主要转移:
7.1 事件①:UI → IA0 / UI → IB0
如果一个或多个 prefetcher 在该 PC 上准确率超过 PB,那么这些 prefetcher 升到 IA0;其他没有达到 PB 的 prefetcher 被降到 IB0。
这意味着:
- Alecto 不是只选唯一最优者
- 它允许多个“足够好”的 prefetcher 同时活跃
这样做是为了平衡 accuracy 与 coverage,而不是只押宝单个 prefetcher。
7.2 事件②:IA0 → UI,IB0 → UI
如果 IA0 的 prefetcher 准确率跌到 PB 以下,它被降回 UI,进入重新观察;若此时没有任何 IA prefetcher,则冷却完成的 IB0 也可回到 UI,一起重新竞争。
这体现出一种“软回退”机制:
不是一旦变差就立刻永久封杀,而是回到试训阶段。
7.3 事件③:UI → IB−N
如果某 prefetcher 在 UI 观察期里准确率甚至低于 DB,说明它明显不适合这个 PC,就被放进最深的阻塞态 IB−N,然后逐周期慢慢升到 IB0,等冷却后再重新评估。
7.4 事件④:IA_m → IA_m+1 / IA_m−1
对于已经适合的 prefetcher:
- 准确率仍高于 PB → 更激进,升一级
- 准确率跌破 DB → 更保守,降一级
所以 IA 状态不仅表示“选中”,还表示“当前激进度级别”。
8. Alecto 如何做动态 demand request allocation
这是论文最精华的部分。
当一个 demand request 到来时,Alecto 用它的 PC 去查 Allocation Table:
- 如果某 prefetcher 处于 UI:为它生成一个 identifier,分配保守 degree
c - 如果某 prefetcher 处于 IA_m:为它生成 identifier,分配更高 degree
c + m + 1 - 如果处于 IB_n:不给 identifier,不分配 request
然后这些 identifier 和 demand request 一起送到多路器,由它把 request 动态路由到指定 prefetcher。
这一步非常重要,因为它带来两个效果:
8.1 只有“该学的人”才能学
不合适的 prefetcher 根本拿不到这个 request,自然就不会:
- 更新错误 metadata
- 浪费训练访问
- 占表项
- 产出重复或错误 prefetch
8.2 selection 与 allocation 融为一体
以前的很多方案是“先让大家都看,再决定采纳谁的输出”;
Alecto 则是在输入阶段就完成选择:
没被选中的 prefetcher,连训练机会都没有。
这和只做 output filter 的思想差异非常大。
9. Sample Table 的两个小设计,其实非常关键
9.1 Demand Counter:定义 epoch
Alecto 不是每条 request 都立刻改状态,而是为每个 PC 维护一个 Demand Counter。
达到一个 epoch(论文实现里约 100 个 demand access)后,再用统计结果更新状态。
这能避免短期噪声导致状态抖动。
9.2 Dead Counter:防止“锁死”
如果某个 PC 还停留在 IA_m,但它的访存模式已经变了,导致当前配置长期发不出 prefetch,那么系统可能陷入“明明状态不对,但因为没发请求,就没有反馈,永远改不回来”的死锁。
为此,Alecto引入 Dead Counter:
- 每次没能产生 prefetch 时增加
- 其他情况下减少
- 一旦高于阈值(如 150),就把该 PC 的所有状态重置回 UI
这个设计很实用,说明作者确实考虑了在线系统的长期运行稳定性。
10. Alecto 为什么能同时提升 accuracy、coverage、timeliness
这是论文论证自己优于 prior work 的核心逻辑。
10.1 accuracy:因为减少了错误训练
不合适的 prefetcher 拿不到 request,自然更少学错、发错。
10.2 coverage:因为不是只选单个最佳
Alecto 不只是保留“accuracy 最高的一个 prefetcher”,而是允许多个高于 PB 的 prefetcher 同时进入 IA,这样能避免 coverage 因过度保守而下降。
10.3 timeliness:因为 IA_m 会逐步加大激进度
一旦确认某 prefetcher 对某 PC 有效,就逐渐增大其 degree,提高预取提前量。
这三者通常是互相拉扯的,但 Alecto 通过“先精细分配训练、再渐进调 degree”实现了较好的平衡。
11. Alecto 对 temporal prefetching 的意义尤其大
这是论文非常值得重视的一部分。
作者明确指出:temporal prefetcher 的 metadata 很贵,不能什么 request 都拿去训练。
很多 request 其实根本不值得送去训练 temporal prefetcher,包括:
- 非 temporal 的访问
- 虽然有 recurrence,但频率太低,metadata 根本留不到下次复现
- 已经能被 stream / stride / spatial 这类低成本非 temporal prefetcher 处理的访问
论文把 temporal 相关模式划分为:
- non-temporal
- stream/stride/spatial 可处理的 temporal
- rare recurrence
- frequent recurrence
Alecto 的作用就是把前几类尽量过滤掉,只把真正值得的那一小部分送给 temporal prefetcher。
这是非常强的 insight,因为它说明:
Alecto 不只是一个“多预取器选择器”,它本质上也是一个 metadata budget allocator。
11.1 与 Triangel 的区别
论文指出 Triangel 虽然也能给 temporal prefetching 做 request allocation,但它:
- 不能过滤由非 temporal prefetcher 可处理的需求
- 存储开销更高(>17KB)
- 与 temporal prefetcher 强耦合,不像 Alecto 那样通用
因此 Alecto 的优势在于:
轻量、通用、可同时管理 temporal 与 non-temporal prefetcher。
12. 论文实验结果应该怎么读
12.1 总体性能
论文总结结果是:
- 单核下,Alecto 相比 Bandit 平均提升 2.76%
- 八核下,相比 Bandit 提升 7.56%
- 在 memory-intensive benchmark 上,相比 Bandit 提升 5.25%
- 同时,prefetcher table access 相关能耗下降 48%
- 整个 memory hierarchy 能耗下降 7%
- 存储开销 小于 1KB
这里要特别注意:
Alecto 的收益在多核、memory-intensive 场景更明显,说明它最擅长解决的确实是共享资源争用下的多预取器冲突问题。
12.2 对非 composite prefetcher 的意义
论文还把 Alecto 管理的 composite prefetcher 与单一高性能 prefetcher(如 PMP、Berti)对比,结果 Alecto 管理的 composite 方案仍然更强,说明:
- “多个 prefetcher + 好的管理器”
- 的确可以优于
- “单个很强的 prefetcher”
这对研究方向判断很重要:
问题不在于多预取器组合本身,而在于你怎么管理它们。
12.3 temporal prefetching 场景
在 temporal prefetching 的代表 benchmark 上:
- Alecto 比 Bandit 好 8.39%
- 比 Triangel 好 2.18%
并且同等 metadata budget 下,Alecto 始终优于 Bandit;为了达到 Bandit 1MB metadata table 的性能,Alecto 只需要不到 256KB。
这个结果很有说服力,因为它不是只说“性能更高”,而是直接说明:
Alecto 更会“省着用 metadata”。
12.4 能耗和训练次数
作者用 prefetcher training occurrence 作为动态功耗的重要 proxy。实验表明:
- Alecto 让各 prefetcher 的训练次数平均减少 48%
- 这也是它能耗下降的重要原因
这和它的设计逻辑是一致的:
少做无意义训练,自然更省能。
13. 作者做的消融实验说明了什么
论文专门做了一个很关键的 ablation:
- 去掉 Alecto 的动态 degree 调节,只保留 request allocation
- 看它还比 Bandit 强多少
结果是:
- 仅靠 request allocation,Alecto 仍比 Bandit6 高 4.34%
- 完整 Alecto 则高 5.25%
这说明:
Alecto 的主要贡献不是 degree tuning,而是 demand request allocation。
这个结论非常重要。因为很多人第一次看这篇论文时,容易把它理解成“又一个 accuracy-threshold-based aggressiveness controller”。其实不是。
真正的第一贡献是:
把预取器管理前移到训练数据分发阶段。
14. 为什么 Alecto 比单纯 prefetch filtering 更有效
论文还拿 Alecto 去和 PPF 这类纯 prefetch filtering 方法对比。
结果表明:
- PPF 确实能提高 accuracy
- 但它常常把有用 prefetch 也过滤掉,coverage 掉太多
- Alecto 相比 IPCP+PPF Aggressive 高 18.38%
- 相比 IPCP+PPF Conservative 高 14.98%
这说明一个很深刻的区别:
- PPF:你已经训练完、已经生成 prefetch 了,再决定删不删
- Alecto:在训练之前就决定谁该收到 request
后者更像从源头治理。
因此,Alecto 不是更强的 prefetch filter,而是更上游的 training-path scheduler。
15. 存储开销与可扩展性
论文给出的结论是:
- 总存储开销约为
5312 + 1792 × Pbits,P 为 prefetcher 个数 - 随 prefetcher 数量线性增长
- 在实验配置
P=3时,总开销约 760 bytes
作者还把它和 Bandit 的扩展版对比:
- 如果让 Bandit 也支持类似的多种 degree 状态,动作空间会指数增长
- 存储约 4KB,是 Alecto 的 5.4 倍
- 而且性能还更差,说明 Bandit 在动作太多时难以收敛
所以 Alecto 的“可扩展性”不是说它能做特别复杂的建模,而是说:
它用非常简单的 per-PC 状态机,避免了 RL 方案在动作空间上的爆炸。
16. 我对这篇论文的评价:它真正厉害的地方是什么
我觉得这篇论文最强的地方不在于“性能数字”,而在于它重新定义了多预取器管理问题。
以前很多工作默认:
所有 demand request 都可以当作公共训练流,重点是最后怎么选择输出。
Alecto 则提出:
训练输入本身就是需要调度和隔离的对象。
这是一个很重要的视角变化。
它意味着多 prefetcher 管理问题,不仅是:
- 哪个 prefetcher 开
- 哪个关
- degree 多大
更是:
- 谁有资格看哪些 training sample
这个思想和很多体系结构问题其实是共通的,比如:
- branch predictor 的训练污染
- replacement policy 的 signature 污染
- ML 加速器中 expert routing / mixture-of-experts
Alecto 的思路,某种程度上就是 给 prefetcher 做 expert routing。
17. 这篇论文的局限性
虽然我认为这篇工作很扎实,但它也有明显局限。
17.1 识别信号仍然比较单一
Alecto 用的 suitability 主要还是 accuracy。
这比 Bandit 的 phase-level 组合选择更细,但它依然没有显式建模:
- timeliness
- cache pollution
- bandwidth pressure
- 不同 prefetcher 之间的互相伤害程度
这也是后续 I-POP 会批评 Alecto 的地方:accuracy 不足以完整表征对 IPC 的真实影响。
17.2 粒度是 per-PC,不是 per-context
一个 PC 在不同上下文、不同 phase 下,可能对应不同访存模式。
Alecto 通过 epoch 和状态回退缓解了这个问题,但本质上它仍然是:
- 用 PC 聚合模式
- 再用状态机去适应变化
因此在某些高度 phase-sensitive 或 same-PC-multi-pattern 的程序中,仍可能不够精细。
17.3 适合“可按 PC 局部稳定建模”的模式
Alecto 的假设是“同一个 memory access instruction 的行为有一定一致性”。这在很多程序里成立,但对某些数据依赖极强、上下文差异特别大的 irregular workload,可能没那么稳。
18. 和你前面研究过的几篇工作怎么对应
结合你之前关注的多预取器管理论文,可以这样理解它们的谱系:
DOL
核心是“功能分工”,偏静态协作。
问题在于优先级固定,缺乏动态反馈。
IPCP
本质上是“多个子预取器的静态分层优先级输出融合”,仍然没有解决输入训练污染。
Bandit / RL
尝试动态选择组合和 degree,但更多是在 phase 级别控制“输出策略”,没有解决“训练样本该给谁”。
Alecto
第一次把重点真正放到:
demand request allocation + fine-grained PC-level identification
I-POP
再进一步,批评 Alecto 用 accuracy 做控制信号仍不够好,转而提出更接近“净性能贡献”的 PE 指标。
所以如果做一条研究演进线,大概是:
静态协作 → 动态组合选择 → 动态训练分配 → 基于性能净效应的统一量化控制
Alecto 处在其中一个非常关键的中间节点。
19. 最后的总结
这篇论文最值得记住的,不是“Alecto 比 Bandit 快 2.76%”这种数字,而是下面三点:
第一,它把问题前移了
它认为多预取器管理不该只在输出端做,而应该在输入训练阶段就开始做。
这是它最核心的创新。
第二,它把粒度细化到 PC
不是全局选最优 prefetcher,而是对每个 PC 单独判断谁适合、谁不适合。
这让它能同时兼顾 accuracy、coverage 和 timeliness。
第三,它对 temporal prefetching 特别有意义
temporal prefetcher 的 metadata 非常贵,Alecto 证明了:
把不值得的 demand request 过滤在外,往往比盲目扩大 metadata 更有效。
如果你愿意,我下一步可以继续给你做一版:
“Alecto 与 DOL / IPCP / Bandit / I-POP 的逐项对比表”,把设计目标、控制粒度、输入分配、输出仲裁、度量指标、硬件开销和适用层级一次性梳理清楚。