A cache simulator that investigates how prefetching aggressiveness interacts with cache associativity across different memory access patterns.
Can next-line prefetching improve cache hit rate beyond spatial/temporal locality, and at what point does prefetch aggressiveness hurt more than it helps?
This project simulates CPU cache behaviour on real programs. A custom C simulator replays Valgrind memory traces through a configurable L1 cache model, measuring:
- Hit rate across access patterns and cache configurations
- Miss classification (compulsory, conflict, capacity) via a shadow fully-associative cache
- Prefetch usefulness and cache pollution across prefetch distances 0–16
- C — Cache simulator
- Python (pandas, matplotlib, seaborn) — Analysis and visualisation
- Valgrind Lackey — Memory trace generation
- Docker — Cross-platform reproducibility
Requires Docker Desktop. No other dependencies needed.
git clone <your-repo>
cd cacheSim
docker-compose upResults and graphs appear in the results/ folder.
Requires gcc, valgrind, python3.
pip install pandas matplotlib seaborn
./run_sim.sh./cache_sim clean_trace.txt -s 4096 -a 1 -b 16 -p 4| Flag | Description | Default |
|---|---|---|
-s |
Cache size in bytes | 4096 |
-a |
Associativity (1=direct-mapped, N=N-way, 256=fully associative) | 1 |
-b |
Block size in bytes | 16 |
-p |
Prefetch distance (blocks ahead to speculatively load) | 0 |
Running the simulation produces the following in results/:
results.csv— full data across all 54 configurationshitrate_workload.png— hit rate by pattern and associativityprefetch_hitrate.png— hit rate vs prefetch distanceconflict.png— conflict misses by associativityprefetch_efficiency.png— prefetch usefulness vs distancepollution.png— cache pollution vs distanceheatmap.png— correlation matrix of cache metrics
