# How to Use the Python API for Cache Simulation in libCacheSim: A Complete Guide

> Learn to use the Python API for cache simulation in libCacheSim. Easily analyze miss-ratio curves with lightweight wrappers and parsed output. Get started today.

- Repository: [Juncheng Yang/libcachesim](https://github.com/1a1a11a/libcachesim)
- Tags: how-to-guide
- Published: 2026-02-23

---

**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`](https://github.com/1a1a11a/libcachesim/blob/main/scripts/utils/setup_utils.py)**: Contains the `setup()` function that detects missing `bin/cachesim` and compiles it automatically ([source lines 45-53](https://github.com/1a1a11a/libcachesim/blob/develop/scripts/utils/setup_utils.py#L45-L53)).
- **[`scripts/plot_mrc_size.py`](https://github.com/1a1a11a/libcachesim/blob/main/scripts/plot_mrc_size.py)**: Provides `run_cachesim_size()` to execute size-based simulations and `_parse_cachesim_output()` to transform results into Python objects ([source lines 23-53](https://github.com/1a1a11a/libcachesim/blob/develop/scripts/plot_mrc_size.py#L23-L53)).
- **[`scripts/plot_mrc_time.py`](https://github.com/1a1a11a/libcachesim/blob/main/scripts/plot_mrc_time.py)**: Offers `run_cachesim_time()` for time-varying miss-ratio analysis.
- **[`scripts/benchmark_throughput.py`](https://github.com/1a1a11a/libcachesim/blob/main/scripts/benchmark_throughput.py)**: Wraps simulations with Linux `perf` to 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.

```python
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`](https://github.com/1a1a11a/libcachesim/blob/main/scripts/plot_mrc_size.py) executes the simulator across a range of cache sizes and returns structured data for plotting miss-ratio curves (MRC).

```python
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 via `subprocess.run` ([source lines 56-70](https://github.com/1a1a11a/libcachesim/blob/develop/scripts/plot_mrc_size.py#L56-L70)).
- 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](https://github.com/1a1a11a/libcachesim/blob/develop/scripts/plot_mrc_size.py#L64-L94)).

## Running Time-Based Cache Simulations

For analyzing how miss ratios evolve over time, use the time-based API in [`scripts/plot_mrc_time.py`](https://github.com/1a1a11a/libcachesim/blob/main/scripts/plot_mrc_time.py). The interface mirrors the size-based version but requests time-varying statistics from the simulator.

```python
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`](https://github.com/1a1a11a/libcachesim/blob/main/benchmark_throughput.py) module. The `run_cachesim()` function wraps the binary execution with Linux `perf` and parses the output via `parse_perf_stat()`.

```python
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.

```python
#!/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 C `cachesim` binary via subprocess calls.
- **`setup()`** in [`scripts/utils/setup_utils.py`](https://github.com/1a1a11a/libcachesim/blob/main/scripts/utils/setup_utils.py) automatically compiles the simulator on first use by checking `CACHESIM_PATH`.
- **`run_cachesim_size()`** and **`run_cachesim_time()`** execute simulations and return `(dataname, mrc_dict, cache_has_units)` tuples for analysis.
- The **`_parse_cachesim_output()`** function in [`scripts/plot_mrc_size.py`](https://github.com/1a1a11a/libcachesim/blob/main/scripts/plot_mrc_size.py) handles 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`](https://github.com/1a1a11a/libcachesim/blob/main/scripts/utils/setup_utils.py) automatically detects if `bin/cachesim` is missing and compiles it from the `src/` directory ([source lines 45-53](https://github.com/1a1a11a/libcachesim/blob/develop/scripts/utils/setup_utils.py#L45-L53)). 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`](https://github.com/1a1a11a/libcachesim/blob/main/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()`.