缓存包含/排除策略

共 17 题
📑 题目列表 17 题
#
★★★

1. Inclusive cache(L3 包含 L1/L2 all lines)的工程优势,snoop filter 与 coherency 如何受益?

Inclusive cache(L3 包含 L1/L2 的所有 line)的工程优势是什么?如何体现在 snoop filter、coherency 上?

  • inclusive 缓存包含关系
  • snoop filter 的命中判断
  • 一致性维护的简化

Inclusive cache 中,L3 包含 L1/L2 的所有 line(L1/L2 的每一行都在 L3 有副本)。工程优势:一致性维护更简单——snoop 时只需查 L3 就能判断某 line 是否在芯片内(L1/L2),无需逐核广播 snoop 每个私有缓存,L3 天然充当 snoop filter;命中 L3 即知是否在其他核缓存,未命中则无需访问 DRAM 即可确定无缓存副本。这减少 snoop 流量与一致性延迟。代价是 L3 显存开销大(重复存储)且 L3 替换时需 invalidate 下级缓存。Intel 的 L3 多为 inclusive,snoop filter 由 L3 承担,一致性/性能更优。

Inclusive 用 L3 存所有 line 副本,使 L3 充当 snoop filter,snoop 判断本地化、无需广播,简化一致性并降低延迟,是 inclusive 的核心价值。

#
★★

2. Exclusive cache(L2 与 L3 互斥, victim out)的工程优势,为何带来更大 effective cache?

Exclusive cache(L2 与 L3 互斥,victim out)的工程优势是什么?如何实现更大 effective cache?

  • exclusive 的互斥关系
  • victim 迁移到 L3
  • 有效缓存容量

Exclusive cache 中 L2 与 L3 互斥,一个 line 只存在于 L2 或 L3(不重复),L2 替换(victim)出去的 line 被放入 L3 而非丢弃。工程优势:总有效缓存容量更大(L2+L3 之和,无重复存储),同等缓存预算下能缓存更多数据,减少 DRAM 访问;victim 不丢失,数据仍在 L3 中。代价是 L3 命中路径略复杂(需维护 line 归属),且 L3 不像 inclusive 那样能天然充当 snoop filter。AMD 的 L3 采用 non-inclusive/exclusive 风格,牺牲 snoop filter 简单性换取更大有效容量。

Exclusive 消除层级重复,把 L2 替换出的 line 迁到 L3,使有效缓存容量接近 L2+L3 之和,实现更大缓存效果,但失去 inclusive 的 snoop filter 简化。

#
★★

3. Inclusive cache 在 victim eviction 时强制 invalidate L1/L2 的开销?

Inclusive cache 在 victim eviction 时强制 invalidate L1/L2 的开销是什么?

  • inclusive 的替换需维护下级
  • invalidate L1/L2 的开销
  • 缓存缺失与一致性代价

Inclusive cache 中,当 L3 的一个 line 被替换(victim eviction)时,必须强制 invalidate 所有下级缓存(L1/L2)中该 line 的副本,以保持包含关系。这带来开销:被 invalidate 的 line 若仍被某核频繁使用,会强制重新从 DRAM 读取,造成缓存缺失与性能损失;invalidate 操作也产生一致性/管理流量。因此在 L3 频繁替换的场景(多核竞争、大工作集),inclusive 会因强制 invalidate 而损失更多性能。这是 inclusive 相对 exclusive 的主要代价,工程上需权衡"一致性简化"与"替换开销"。

Inclusive 的包含关系要求在 L3 替换时同步 invalidate 下级副本,若副本仍被使用则导致额外缺失,这是 inclusive 替换路径的性能代价。

#
★★

4. MOESI 相对 MESI 增加的 Owned 状态在 AMD Zen 的工程价值?

MOESI 相对 MESI 增加的 Owned 状态在 AMD Zen 上的工程价值是什么?

  • MOESI 的 O 状态
  • 共享脏数据的直接转发
  • AMD Zen 的协议实现

MOESI 在 MESI 基础上增加 Owned(O)状态:O 表示该核拥有"脏(修改)"数据但允许其他核共享(读),即"唯一直写者 + 多读共享者"。工程价值:当共享的脏数据需要被其他核读时,O 状态让数据可被直接转发,无需先写回内存再读,减少往返与内存流量;同时避免 M 状态独占导致的频繁 writeback。AMD Zen 的 L2 使用 MOESI(Zen 的 L3 是 non-inclusive,采用 MOESI 协议),提升共享数据的一致性与访存效率,尤其适合多核共享读写频繁的场景。相比 MESI 的 overall 写回-共享切换,O 状态减少一致性流量。

O 状态让"脏数据可共享传播",避免共享脏数据必须写回内存,降低一致性流量与延迟,是 MOESI 在 Zen 多核上的核心价值。

#
★★

5. MESIF 中 Forward 状态在 Intel scalable ring 的 snoop forwarding 优化?

MESIF 中 Forward 状态在 Intel scalable ring 的 snoop forwarding 优化是什么?

  • MESIF 的 F 状态
  • snoop forwarding 的指定
  • Intel ring 的一致性优化

MESIF 在 MESI 基础上增加 Forward(F)状态,用于多核共享数据时指定一个"唯一响应者":当多个核共有只读数据时,F 状态的核负责响应对该数据的 snoop 请求(forward 数据给请求者),避免多个核同时响应导致的一致性与带宽问题。在 Intel 的 scalable ring(环形互联)上,F 状态明确指定哪个核作 snoop 响应者,减少了 snoop 的广播与竞争,优化一致性流量。工程价值:多核共享只读数据(如共享库、常见数据)时,F 状态指定单点响应,降低 snoop 延迟与互联带宽,提升一致性性能。

F 状态在共享只读数据中指定唯一 forward 响应者,避免多核并发响应,减少 snoop 广播与竞争,是 Intel ring 一致性优化的关键。

#
★★

6. MOESI 在 Directory-based coherence(AMD Zen CCX)的广播抑制?

MOESI 在 Directory-based coherence(AMD Zen CCX)中如何实现广播抑制?

  • Directory-based coherence
  • 广播抑制的机制
  • AMD Zen CCX 的实现

Directory-based coherence 用一个目录(directory)记录每个 cache line 的共享者(哪些核持有),从而在 snoop 时只向"持有该 line 的核"发送请求,而非广播给所有核。AMD Zen 的 CCX 采用 directory-based 一致性,目录记录 line 的 owner 与 sharers,配合 MOESI 协议,需要时只向 sharer 发 snoop 请求,抑制不必要的广播。工程价值:广播抑制减少 snoop 流量与互联带宽压力,尤其在多核高共享场景提升可扩展性;MOESI 的 O 状态与目录结合,让共享脏数据转发更高效。代价是目录有一定存储与带宽开销,且需维护目录一致性。

Directory 记录共享者,snoop 从"全广播"变为"定向请求",抑制广播流量,是 CCX 多核一致性的关键,MOESI 提供状态语义。

#
★★

7. MESI 与 MOESI 在 directory protocol 实现的工程取舍?

MESI 与 MOESI 在 directory protocol 实现中的工程取舍是什么?

  • MESI 的简单性
  • MOESI 的 O 状态
  • 目录实现的复杂度与性能

MESI 状态更少(M/E/S/I),目录实现简单、状态转换少、目录位少,硬件成本低,但共享脏数据需写回内存才能传播,一致性流量较多;MOESI 增加 O 状态,允许脏数据共享转发,减少写回与流量,但状态与转换更复杂,目录需管理 O 的共享者信息,实现成本和验证复杂度更高。工程取舍:MESI 简单、面积小、易实现,适合一致性要求不高或资源受限场景;MOESI 性能好、流量低,适合高性能多核但实现复杂。AMD Zen 用 MOESI(directory),Intel 用 MESIF(inclusive),都是在"复杂度"与"性能/流量"间的取舍。

MESI 以简单换取低实现成本,MOESI 以复杂度换取低一致性流量与高性能,directory 实现中二者的取舍是状态数、目录位与性能的权衡。

#
★★

8. Flush+Reload 利用共享(如 L3 inclusive)缓存,通过 clflush 后测量 reload 时间推断受害者访问了哪些缓存行,其原理是什么?

Flush+Reload 利用共享(如 L3 inclusive)缓存,通过 clflush 后测量 reload 时间推断受害者访问的缓存行,其原理是什么?

  • Flush+Reload 的攻击流程
  • clflush 与 reload 时序
  • 共享缓存/channel 的利用

Flush+Reload 是缓存侧信道攻击,适用于共享缓存(如 inclusive L3 或共享内存页)。攻击流程:攻击者用 clflush 把目标缓存行从缓存中驱逐(flush 掉),然后监听受害者是否访问该行;若受害者访问了,该行被重新加载进缓存,攻击者随后 reload 该行并测量时间——若命中(时间短)说明受害者访问过,若未命中(时间长)说明未访问。原理:共享缓存/共享内存使攻击者与受害者共用相同缓存行,通过 clflush+reload 的时序差异区分"受害者的访问足迹",从而推断受害者访问了哪些地址(如 RSA 密钥位)。它要求攻击者与受害者共享物理页(如共享库、Linux 页共享)。

核心是利用"缓存状态可被攻击者控制(flush)与观测(reload)"以及物理页共享,用时序差异推断受害者访问模式,是缓存侧信道的基础。

#
★★

9. Spectre v1 如何诱导分支预测器误预测,使越界 load 的数据进入缓存,再通过侧信道逐字节泄漏?

Spectre v1 如何诱导分支预测器误预测,使越界 load 的数据进入缓存,再通过侧信道逐字节泄漏?

  • 分支预测的投机执行
  • 越界 load 与数组索引
  • Flush+Reload 逐字节泄漏

Spectre v1(Bounds Check Bypass)诱导分支预测器误预测一个边界检查分支(如 if (x < size)),使 CPU 在 x 越界时仍投机执行,加载越界数组元素(如 data[offset]),再用该值作为索引访问一个探测数组(cache 提权),探测数组因该越界数据被装进缓存。之后分支被纠正、投机结果被丢弃,但缓存状态已被污染。攻击者用 Flush+Reload 等时序侧信道探测缓存,推断越界数据(如密钥字节)——因为探测数组里哪个元素被缓存就对应数据值。逐字节重复即可泄漏内存。

Spectre 利用投机执行"提前执行但丢弃结果",副作用(缓存)残留成为侧信道,越界 load 把机密数据映射到缓存,再经时序泄露,是推测执行安全的经典攻击。

#
★★

10. Meltdown 如何利用乱序执行在异常被交付前完成对内核内存的越界访问,并把结果编码进缓存状态?

Meltdown 如何利用乱序执行在异常被交付前完成对内核内存的越界访问,并把结果编码进缓存状态?

  • 乱序执行的投机访问
  • 异常延迟交付
  • 结果编码进缓存

Meltdown 利用乱序执行与异常交付的时序差。攻击者执行一条访问内核内存的指令(如 mov al, [addr],该地址无权限),在越权异常被交付(serialize)之前,CPU 已乱序执行该 load 并把数据读入寄存器;随后 CPU 用该数据(如作为索引)访问一个探测数组,把对应缓存行装进缓存。当异常最终交付时,指令被丢弃、寄存器结果作废,但缓存状态已被污染。攻击者用 Flush+Reload 探测缓存,推断被访问的内核数据(如地址)——探测数组哪个元素在缓存即对应数据值。逐字节即可跨权限读取内核内存。

Meltdown 的核心是"乱序执行先于异常交付",把无权限读到的数据映射到缓存,异常丢弃指令但缓存副作用残留,经时序侧信道提取,是推测执行泄露的经典案例。

#
★★

11. 为什么缓存侧信道的根源是微架构状态(缓存/TLB)依赖了机密数据?常数时间编程如何消除这类泄漏?

为什么缓存侧信道的根源是微架构状态(缓存/TLB)依赖了机密数据?常数时间编程如何消除这类泄漏?

  • 微架构状态泄漏
  • 机密数据依赖缓存/TLB
  • 常数时间编程

缓存侧信道的根源是:当程序处理机密数据时,其访问模式(哪些缓存行被加载、哪些 TLB 条目被填)依赖机密数据的值,这种"机密数据→微架构状态"的依赖可通过时序被外部观测,从而泄露机密。常数时间编程(constant-time programming)消除这种依赖:保证代码的执行时间与缓存访问模式不依赖于机密数据,例如用位运算(无分支)替代依赖数据的分支、预加载所有可能的缓存行(避免分支选择)、用固定表访问(无论数据值都访问同样位置)。这样机密数据不再影响微架构状态,外部时序无法推断机密,从而消除侧信道。

泄漏的本质是"机密数据影响微架构状态",常数时间编程切断"数据→分支/缓存依赖",使执行与机密无关,从根源消除时序侧信道。

#
★★

12. Meltdown 的防御 KPTI(页表隔离)把内核与用户页表分开,带来了什么性能开销?

Meltdown 的防御 KPTI(页表隔离)把内核与用户页表分开,带来了什么性能开销?

  • KPTI 的页表隔离
  • 上下文切换开销
  • 系统调用/中断的 TLB 刷新

KPTI(Kernel Page Table Isolation)把用户态页表与内核页表分开,用户态只映射用户页(不含内核),内核态才映射内核页,从而阻止用户态通过 Meltdown 读取内核内存。代价:每次用户态<->内核态切换(系统调用、中断、异常)需切换页表并刷新 TLB(或使用 PCID 部分刷新),导致 TLB 冷启动与上下文切换开销;系统调用、调度、页错误等频繁切换场景性能下降明显(尤其 IO 密集、系统调用密集的负载)。工程上 KPTI 用 PCID 加速(避免全量 TLB flush),但仍有显著开销,是安全与性能的换取。

KPTI 通过页表隔离消除 Meltdown 面,代价是每次特权级切换的 TLB 刷新与页表切换开销,属于"安全换性能"的典型权衡。

#
★★

13. 为什么 inclusive 缓存策略让跨核/跨进程的缓存侧信道更容易,而 exclusive/non-inclusive 能部分缓解?

为什么 inclusive 缓存策略让跨核/跨进程的缓存侧信道更容易,而 exclusive/non-inclusive 能部分缓解?

  • inclusive 的共享 L3
  • 侧信道需要共享缓存
  • exclusive/non-inclusive 的隔离

Inclusive 缓存中,L3 包含所有核 L1/L2 的 line,攻击者与受害者即便在不同核/进程,只要访问同一物理页(共享内存、共享库),其 line 都存在于共享的 L3 中,攻击者可在 L3 层面执行 Flush+Reload/Prime+Probe,跨核观测受害者访问,侧信道更容易建立。exclusive/non-inclusive 缓存中,L3 不保留所有下级副本、line 归属更分散,攻击者难以在单一共享 L3 上稳定观测其他核的访问(line 可能只在某核私有缓存中),跨核侧信道更难建立,部分缓解了泄漏。因此 inclusive 因共享 L3 的集中性更易被跨核侧信道利用。

侧信道依赖"攻击者与受害者共享可观测的缓存状态",inclusive 的共享 L3 提供统一观测点,exclusive/non-inclusive 分散 line 归属,削弱共享观测,从而缓解跨核侧信道。

#

14. CXL.memory device 与本地 cache 的 inclusive 协议边界?

CXL.memory device 与本地 cache 的 inclusive 协议边界是什么?

  • CXL 内存与本地缓存一致性
  • inclusive 边界的语义
  • 设备内存的缓存一致性

CXL.memory device(如 Type-3 扩展内存)通过 CXL.mem 协议接入,与本地 cache 的一致性由 CXL 协议保证。inclusive 协议边界指:CXL 内存设备是否作为"包含"层(像 inclusive L3 一样包含主机缓存副本)还是"非包含"(仅作为内存,主机缓存管理副本)。工程上,CXL Type-3 通常作为内存存在,主机 L1/L2/L3 缓存其数据,通过 CXL.mem 的 coherence 机制(如 D2H 请求、back-invalidate)保证一致性,协议边界由 CXL.cache/mem 的模型决定(HBI/coherence 模式)。边界明确后,主机缓存与设备内存间的一致性由 CXL 协议处理,避免设备内存与本地缓存不一致。

CXL 内存的 inclusive 边界决定设备内存与主机缓存的包含关系和一致性协议,是否包含主机副本影响一致性与性能,是 CXL 内存拓扑的关键。

#

15. Spectre 的防御(lfence 序列化、retpoline、IBRS/IBPB)各自针对推测执行的哪个环节?

Spectre 的防御(lfence 序列化、retpoline、IBRS/IBPB)各自针对推测执行的哪个环节?

  • lfence 的序列化
  • retpoline 抑制 ret 预测
  • IBRS/IBPB 的预测抑制

Spectre 的防御针对推测执行的不同环节:lfence 是序列化指令,阻止其后的指令被投机执行,阻断"分支误预测→越界 load"的投机窗口,用于 Spectre v1 的边界检查场景;retpoline 用间接跳转包裹替代 ret 指令,抑制 ret 的推测式预测(BTB),阻断 Spectre v2 的"间接分支污染";IBRS(Indirect Branch Restricted Speculation)限制间接分支预测到更高权限的预测器,防止跨权限 IP 污染;IBPB(Indirect Branch Prediction Barrier)在权限切换处冲刷间接分支预测器,防止攻击者污染受害者后续预测。三者分别针对分支预测、ret 预测、预测器污染等环节。

lfence 阻断投机执行窗口,retpoline 化解 ret 预测,IBRS/IBPB 限制与冲刷预测器防止跨上下文污染,分别对应推测执行的不同漏洞面。

#

16. Intel L3 inclusive 与 AMD Zen L3 non-inclusive(非独占但 victim out)的实现差异?

Intel L3 inclusive 与 AMD Zen L3 non-inclusive(非独占但 victim out)的实现差异是什么?

  • Intel inclusive 包含副本
  • AMD Zen non-inclusive 的 victim out
  • 一致性/容量差异

Intel 的 L3 是 inclusive:L3 包含 L1/L2 的所有 line 副本,L3 充当 snoop filter,一致性判断本地化,但 L3 有重复存储开销、替换时需 invalidate 下级;AMD Zen 的 L3 是 non-inclusive(非独占,victim out):L3 不强制包含所有下级 line,L2 替换出的 line 可迁移到 L3(victim out,类似 exclusive 的某些特性),但 L3 也可能有不在 L2 的 line。差异:Intel inclusive 简化一致性但牺牲有效容量,AMD non-inclusive 有效缓存容量更大、避免重复存储,但一致性需用 directory(snoop 定向)而非 L3 天然过滤。这与 Zen 用 directory-based MOESI 相配合。

Intel 用 inclusive 换取 snoop filter 简化,AMD 用 non-inclusive 换更大有效容量,配合 directory 一致性,是两种缓存包含策略的典型实现差异。

#

17. Prime+Probe 与 Flush+Reload 的区别是什么?为什么 Prime+Probe 不需要与受害者共享物理页也能工作?

Prime+Probe 与 Flush+Reload 的区别是什么?为什么 Prime+Probe 不需要与受害者共享物理页也能工作?

  • Flush+Reload 需共享物理页
  • Prime+Probe 的缓存集合攻击
  • 不共享物理页的可行性

Flush+Reload 要求攻击者与受害者共享同一物理页(共享库、共享内存),攻击者 clflush 后 reload 该页缓存行,共享缓存行才能观测受害者访问;Prime+Probe 不需要共享物理页:攻击者先"prime"(填充)某个缓存集合(cache set,如某路/某组),等待受害者访问,若受害者访问映射到同一缓存集合的地址,会驱逐攻击者填充的 line,攻击者再"probe"(重新访问)该集合,测量时间判断受害者是否访问过该集合。Prime+Probe 通过"缓存集合占用"而非"共享 line"观测,攻击者用自己的缓存集合占据目标集合,受害者访问同集合不同地址也会驱逐,从而无需共享物理页。代价是 Prime+Probe 有噪声(需统计),但适用范围更广。

Flush+Reload 依赖共享物理页的同一缓存行,Prime+Probe 用"攻击者填充缓存集合 + 受害者驱逐"的观测,填充的是攻击者自己的地址,故无需共享物理页,只要与受害者映射到同一缓存集合。