Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

A simulator to demonstrate the performance advantages of ARC (Adaptive Replacement Cache) against LRU, LFU, and OPT under various workloads.

Notifications You must be signed in to change notification settings

YouXiangyu/cache-algorithm-simulator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

23 Commits

Repository files navigation

CAPSA - 缓存算法性能模拟器与分析器

  • 创建/更新时间:2025年12月20日

简介

CAPSA 是一个轻量级缓存性能模拟器,用于在相同的访问序列上比较 ARC、LRU、LFU、FIFO、2Q 和理论最优 OPT 算法。所有内置负载由 capsa/trace_suite.py 使用基于函数的脚本动态生成,无需预生成的跟踪文件。

核心特性

  • 固定缓存大小:32 页
  • 固定请求数:每个负载 50000 次请求
  • 7 个内置负载:覆盖不同算法的优势场景
  • 两种使用模式:带数字参数的命令行或交互式 CLI 菜单
  • 动态生成:所有负载实时生成,保证可重现性
  • 简单设计:使用循环、条件分支和均匀分布,避免复杂随机

系统要求

  • Python 3.10+

快速启动

命令行:

# 克隆或下载项目后,直接运行
python main.py

运行示例

# 方式1:交互式菜单(推荐)
python main.py
# 方式2:命令行参数
python main.py -1 # 运行负载 1
python main.py -1 -3 -5 # 运行负载 1、3 和 5
python main.py -7 # 运行第 7 个负载(WL07)
# 方式3:运行所有负载并显示汇总表(推荐用于快速对比)
python main.py -all # 运行所有负载,显示美观的命中率汇总表
# 生成实际负载(可选)
python generate_fixed_traces.py

交互式菜单将显示所有 7 个负载及其特征,您可以:

  • 输入用空格或逗号分隔的负载编号(例如,1 3 51,3,5)
  • 按 Enter 运行所有负载
  • 选择多个负载进行批量分析

7 种负载详解

以下描述直接对照 capsa/trace_suite.py,确保注释与实现一一对应,并聚焦于设计思路与关键特征。

WL01_STATIC_FREQ — 静态频率模式

设计思路

  • 热集:页面 1-5,在每轮中分别访问 100 次(合计 500 次请求)。
  • 冷集:页面 6-105,每轮各访问 1 次(100 次请求)。
  • 共 600 次请求/轮,循环约 83 轮后裁剪到 50000 次请求。

关键特征

  • 热集频率远高于冷集,LFU 能稳定锁定热页。
  • LRU/2Q 需要不断腾挪冷页,容易被冷集刷新。

WL02_FREQ_BALANCED — 频率平衡模式

设计思路

  • 热集:页面 1-20,每轮 10 次访问(200 次请求)。
  • 温集:页面 21-60,每轮 1 次访问(40 次请求)。
  • 每轮 240 次请求,循环约 208 轮并裁剪至 50000。

关键特征

  • 工作集 60 页覆盖热+温,远大于缓存 32 页。
  • 热集与温集频率差距有限,测试 LFU 在"刚好逼近缓存"时的稳定性。

WL03_STATIC_SW — 静态滑动窗口

设计思路

  • 维护一个 28 页窗口(略小于缓存 32 页)。
  • 窗口每次滑动 1 页,按顺序访问窗口内的所有页面。
  • 通过移动窗口循环覆盖数百页,并裁剪为 50000 次请求。

关键特征

  • 纯粹的最近使用场景,无频率信息可用。
  • LRU/ARC 等基于 recency 的算法可以稳定保持 28 页工作集。

WL04_FIFO_CONVOY — 污染+切换

设计思路

  • 污染阶段:页面 1-32 被访问 50 轮,使 LFU 计数拉满。
  • 切换阶段:立即改为循环访问页面 33-64,直到补足 50000 次请求。
  • 由于切换阶段页面数等于缓存容量,命中率理论上可接近 100%。

关键特征

  • LFU 在切换后仍"抱紧"旧热集,命中率暴跌。
  • 只关注栈距离的算法(LRU、FIFO、ARC、2Q)能快速替换旧页面,几乎全命中。

WL05_SCAN_SANDWICH — 热浪 + 双滑窗 + 长扫描

设计思路

  • 热浪:三个 10 页热集依次访问,重复次数依次为 5/4/3。
  • 双滑窗:两个 32 页窗口在不同起点扫描。
  • 热桥:热集 1 与热集 3 交替访问以恢复热点。
  • 大窗口:两个 48 页窗口继续扫描。
  • 冷扫描:一次性访问 200 个唯一页面后进入下一轮,循环直至 50000。

关键特征

  • 单轮内包含频率积累、短窗口、长窗口与冷扫描,模式切换极为频繁。
  • 考察 2Q/ARC 对多阶段突变的响应,以及算法如何在极端"扫描夹层"中保住热集。

WL06_ARC_MOSAIC — 热集 + 滑窗 + 冷扫描杂合

设计思路

  • 阶段 A:页面 1-6 重复 12 次(72 次请求)。
  • 阶段 B:30 页滑动窗口一次扫描,起点随轮漂移。
  • 阶段 C:页面 31-36 循环 6 次,并插入桥接页 90-105。
  • 阶段 D:扫描 60 个唯一页面后立即回到两个热集。

关键特征

  • 以更短的四段结构复刻 ARC 常见场景:频率 → 最近使用 → 热集切换 → 冷扫描。
  • 能快速观察 ARC 如何凭借 T1/T2 调节跨阶段恢复命中率。

WL07_ADAPTIVE_MIXED — 模式轮换

设计思路

  • 每 5000 次请求切换一次模式:
    • 模式 1:热集(1-5)高频 + 冷集(6-20)单次访问。
    • 模式 2:30 页滑动窗口,窗口起点随阶段推进。
    • 模式 3:长扫描中每 50 次插入 5 次热集访问。
  • 循环三个模式直到 50000 次请求。

关键特征

  • 将频率、最近使用、扫描三个典型场景以固定节奏串联。
  • 主要用于验证 ARC / 2Q 在长期运行中面对模式突变的自恢复能力。

负载对比表

# 类别 核心特征 最适合算法 关键测试点
1 WL01_STATIC_FREQ LFU 少量热页高频访问,大量冷页低频访问 LFU 频率偏向
2 WL02_FREQ_BALANCED LFU 工作集等于缓存大小,频率vs空间平衡 LFU 频率与空间平衡
3 WL03_STATIC_SW LRU 滑动窗口28(略小于缓存32) LRU 最近使用模式
4 WL04_FIFO_CONVOY FIFO 车队循环6次+扰动尾段 FIFO 顺序队列对齐
5 WL05_SCAN_SANDWICH 2Q WL06扩展变体,双滑窗+多热集+冷扫描 2Q 多阶段自适应
6 WL06_ARC_MOSAIC ARC 热集/滑窗/冷扫描杂合 ARC 多模式混合
7 WL07_ADAPTIVE_MIXED ARC 多种模式每5000次请求切换 ARC 复杂自适应

使用 -all 参数快速对比

以下数据由 python main.py -all 在 2025年11月25日(缓存 32 页、每个负载 50000 次请求)实测获得,列顺序固定为 LFU / LRU / FIFO / 2Q / ARC / OPT(单位:命中率 %):

Workload LFU LRU FIFO 2Q ARC OPT
WL01 83.39 82.57 82.57 82.57 83.39 87.71
WL02 83.32 75.02 75.02 75.02 83.32 88.11
WL03 4.30 96.21 96.21 92.67 96.22 96.24
WL04 3.14 99.87 99.87 99.81 99.81 99.87
WL05 33.42 24.18 24.18 32.81 33.42 33.68
WL06 53.12 45.18 45.18 53.10 53.12 61.44
WL07 44.53 69.87 69.87 70.55 71.63 71.69

该表可直接复制到报告中,用于分析各算法在不同负载下的真实表现。

核心组件

主要文件

main.py

主入口点,提供命令行接口。支持三种模式:

  • 数字参数模式:使用 -1, -2 等参数直接指定负载
  • 交互式菜单模式:不带参数运行,显示所有负载供选择
  • 汇总模式:使用 -all 参数运行所有负载并显示汇总表

主要功能:

  • 解析命令行参数或显示交互菜单
  • 调用 trace_suite.py 生成负载序列
  • 使用 simulator.py 运行模拟
  • 使用 metrics.py 生成性能报告

generate_fixed_traces.py

可选工具,将动态生成的负载序列导出为文本文件。生成的 .trace 文件保存在 traces/ 目录中,可用于外部分析或调试。

核心模块(capsa/)

cache_base.py

定义统一的缓存接口 Cache 抽象基类。所有缓存算法必须实现:

  • access(page_id: int) -> bool:访问页面,返回命中(True)或未命中(False)
  • get_stats() -> Dict[str, int]:返回内部统计信息(如命中/未命中计数)

这确保了所有算法具有统一的接口,便于在相同条件下进行比较。

capsa/caches/

包含 6 种缓存算法的独立实现:

  • lru.py:最近最少使用(LRU)算法,基于 OrderedDict 实现 O(1) 操作
  • lfu.py:最不常用(LFU)算法,按访问频率和 LRU 共同淘汰
  • fifo.py:先进先出(FIFO)算法,使用队列实现
  • arc.py:自适应替换缓存(ARC),实现自适应的 LRU/LFU 混合策略
  • two_q.py:2Q 双队列算法,利用 FIFO 热身队列与 LRU 主队列结合
  • opt.py:理论最优(OPT)算法,需要预知未来访问序列

每个实现都是独立的,可以单独测试和优化。

simulator.py

模拟器核心,负责执行模拟过程:

  • Simulator 类:顺序读取跟踪序列,将每个页面访问传递给缓存算法
  • SimulationResult 数据类:记录模拟结果,包括命中率、未命中数、执行时间等
  • 使用 time.perf_counter_ns() 测量算法开销(非实际 I/O 时间)

metrics.py

性能指标收集器和报告生成器:

  • MetricsCollector 类:将 SimulationResult 转换为人类可读的报告
  • ReportConfig 数据类:配置报告格式和内容
  • 生成包含命中率排名、运行时间排名等信息的详细报告

trace_suite.py

负载定义和生成模块,这是项目的核心:

  • 定义 7 个固定负载的生成函数
  • 每个负载使用函数式编程方式生成,保证可重现性
  • TraceRecipe 数据类:描述每个负载的元数据(键、文件名、类别、目标等)
  • repeat_function():辅助函数,用于重复执行某个函数
  • trim_to_target():辅助函数,确保生成的序列长度恰好为 50000

注意事项

  • 所有负载都是动态生成的,不需要预生成的跟踪文件
  • 所有模拟的缓存大小固定为 32 页
  • 每个负载生成恰好 50000 次请求
  • 所有负载使用简单的循环、条件分支和均匀分布,避免复杂随机
  • 确保不同算法命中率差异明显(10%、30%、60%等),便于对比分析
  • 代码注释为中文,便于理解和维护

About

A simulator to demonstrate the performance advantages of ARC (Adaptive Replacement Cache) against LRU, LFU, and OPT under various workloads.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

Languages

AltStyle によって変換されたページ (->オリジナル) /