How to Use the Python API for Cache Simulation in libCacheSim: A Complete Guide
The libCacheSim Python API provides lightweight wrappers that compile the C simulator on-demand, invoke it via subprocess, and parse plain-text output into Python dictionaries for analyzing miss-ratio curves.
The libCacheSim repository ships a high-performance C implementation of cache-replacement algorithms wrapped in a minimal Python interface. This guide explains how to leverage the Python API to orchestrate simulations, process traces, and visualize results without writing any C code.
Architecture of the Python API for Cache Simulation
Unlike traditional Python bindings that rely on C extensions or ctypes, the libCacheSim Python API operates as a thin orchestration layer within the scripts/ directory. It automatically compiles the cachesim binary from source when needed, executes it via subprocess, and converts space-separated output into native Python structures.
The core components include:
scripts/utils/setup_utils.py: Contains thesetup()function that detects missingbin/cachesimand compiles it automatically (source lines 45-53).scripts/plot_mrc_size.py: Providesrun_cachesim_size()to execute size-based simulations and_parse_cachesim_output()to transform results into Python objects (source lines 23-53).scripts/plot_mrc_time.py: Offersrun_cachesim_time()for time-varying miss-ratio analysis.scripts/benchmark_throughput.py: Wraps simulations with Linuxperfto extract CPU-level performance metrics.
Setting Up the Environment
Before running simulations, ensure the C binary is available. The setup() function handles compilation transparently by checking CACHESIM_PATH and invoking the build system if the binary is absent.
from scripts.utils.setup_utils import setup
# Compiles bin/cachesim from src/ if missing (safe to call multiple times)
setup()
This initialization requires no manual configuration and executes install_dependency() followed by compile_cachesim() to produce the simulator binary.
Running Size-Based Cache Simulations
The run_cachesim_size() function in scripts/plot_mrc_size.py executes the simulator across a range of cache sizes and returns structured data for plotting miss-ratio curves (MRC).
from scripts.plot_mrc_size import run_cachesim_size, plot_mrc_size
# Execute simulation across specified cache sizes
dataname, mrc_dict, cache_has_units = run_cachesim_size(
datapath="/path/to/trace.oracleGeneral",
algos="lru,lfu,arc", # Comma-separated algorithm list
cache_sizes="0.01,0.05,0.1", # Fractions of object count or absolute sizes
ignore_obj_size=True, # Treat all objects as equal size
trace_format="oracleGeneral", # Built-in trace parser
trace_format_params="", # Additional format arguments
num_thread=-1 # -1 uses all available cores
)
# Generate PDF visualization
plot_mrc_size(
mrc_dict=mrc_dict,
cache_size_has_unit=cache_has_units,
use_byte_miss_ratio=False,
name=f"{dataname}_miss_ratio"
)
Key implementation details:
run_cachesim_size()constructs the command line and invokes the binary viasubprocess.run(source lines 56-70).- The internal
_parse_cachesim_output()function converts space-separated fields into tuples of(cache_size, miss_ratio, byte_miss_ratio)and normalizes units when traces contain byte suffixes. plot_mrc_size()renders curves with log-scaled cache sizes and writes a PDF file (source lines 64-94).
Running Time-Based Cache Simulations
For analyzing how miss ratios evolve over time, use the time-based API in scripts/plot_mrc_time.py. The interface mirrors the size-based version but requests time-varying statistics from the simulator.
from scripts.plot_mrc_time import run_cachesim_time, plot_mrc_time
dataname, mrc_dict, cache_has_units = run_cachesim_time(
datapath="/path/to/trace.oracleGeneral",
algos="lru,arc",
cache_sizes="0.05,0.1",
ignore_obj_size=True,
trace_format="oracleGeneral",
num_thread=-1
)
plot_mrc_time(
mrc_dict=mrc_dict,
cache_size_has_unit=cache_has_units,
name=f"{dataname}_time_mrc"
)
Benchmarking Simulator Throughput
To extract CPU performance metrics such as cycles per instruction or throughput (MOPS), use the benchmark_throughput.py module. The run_cachesim() function wraps the binary execution with Linux perf and parses the output via parse_perf_stat().
from scripts.benchmark_throughput import run_cachesim
# Returns dictionary of performance counters
results = run_cachesim(
datapath="trace.oracleGeneral",
algos="lru",
cache_size="0.1",
ignore_obj_size=True
)
Complete Working Example
The following script demonstrates an end-to-end workflow: setup, simulation, and visualization.
#!/usr/bin/env python3
"""Compute and plot size-based MRC for a libCacheSim trace."""
from scripts.utils.setup_utils import setup
from scripts.plot_mrc_size import run_cachesim_size, plot_mrc_size
def main():
# Ensure binary is compiled
setup()
# Configuration
trace = "data/twitter_cluster52.oracleGeneral"
algorithms = "lru,arc,slru"
sizes = "0.01,0.05,0.1,0.2"
# Run simulation
name, mrc, has_units = run_cachesim_size(
datapath=trace,
algos=algorithms,
cache_sizes=sizes,
ignore_obj_size=True,
trace_format="oracleGeneral",
num_thread=-1
)
# Generate visualization
plot_mrc_size(
mrc_dict=mrc,
cache_size_has_unit=has_units,
use_byte_miss_ratio=False,
name=f"{name}_size_mrc"
)
if __name__ == "__main__":
main()
Executing this script produces a PDF named <trace_name>_size_mrc.pdf containing one curve per specified algorithm.
Summary
- The libCacheSim Python API consists of utility scripts in the
scripts/directory that wrap the Ccachesimbinary via subprocess calls. setup()inscripts/utils/setup_utils.pyautomatically compiles the simulator on first use by checkingCACHESIM_PATH.run_cachesim_size()andrun_cachesim_time()execute simulations and return(dataname, mrc_dict, cache_has_units)tuples for analysis.- The
_parse_cachesim_output()function inscripts/plot_mrc_size.pyhandles conversion of plain-text output into Python data structures. - No third-party Python bindings are required; the API uses standard library modules and matplotlib for visualization.
Frequently Asked Questions
Do I need to manually compile the C code before using the Python API?
No. The setup() function in scripts/utils/setup_utils.py automatically detects if bin/cachesim is missing and compiles it from the src/ directory (source lines 45-53). This compilation happens transparently when you import the setup module or call the function directly.
What trace formats does the Python API support?
The API supports all trace formats built into the C simulator, including oracleGeneral, csv, and binary formats. You specify the format using the trace_format parameter in run_cachesim_size() or run_cachesim_time(), and pass additional parser arguments via trace_format_params if the format requires them.
How do I specify multiple cache replacement algorithms in a single run?
Provide a comma-separated string to the algos parameter, such as "lru,lfu,arc" or "fifo,lru,slru". The scripts/utils/cachesim_utils.py module maintains the mapping between these human-readable names and the internal identifiers used by the C binary.
Can I retrieve simulation results without generating plots?
Yes. The run_cachesim_size() and run_cachesim_time() functions return raw data in the mrc_dict dictionary, which maps algorithm names to lists of (cache_size, miss_ratio, byte_miss_ratio) tuples. You can process this data programmatically without calling plot_mrc_size() or plot_mrc_time().
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →