A configurable, cycle-accurate cache hierarchy simulator written in C++. Simulates an L1 and optional L2 cache with set-associative organization, LRU replacement, and write-back / write-allocate policy. Accepts real memory-access trace files and reports detailed hit/miss/writeback statistics.
- Configurable L1 and L2 caches (size, associativity, block size)
- LRU (Least Recently Used) replacement policy
- Write-back + write-allocate policy
- Accurate memory traffic calculation
- Optional L2 cache (disabled by setting L2_SIZE to 0)
- Stream prefetcher parameter interface (PREF_N / PREF_M accepted)
Requires g++ and make.
makeThis produces the sim binary.
./sim <BLOCKSIZE> <L1_SIZE> <L1_ASSOC> <L2_SIZE> <L2_ASSOC> <PREF_N> <PREF_M> <trace_file>
| Parameter | Description |
|---|---|
BLOCKSIZE |
Block size in bytes (must be a power of 2) |
L1_SIZE |
L1 cache size in bytes |
L1_ASSOC |
L1 associativity (number of ways) |
L2_SIZE |
L2 cache size in bytes (0 = no L2) |
L2_ASSOC |
L2 associativity |
PREF_N |
Stream prefetcher N parameter (0 = disabled) |
PREF_M |
Stream prefetcher M parameter |
trace_file |
Path to memory access trace file |
L1-only cache (no L2):
./sim 32 8192 4 0 0 0 0 trace.txtL1 + L2 hierarchy:
./sim 32 8192 4 262144 8 0 0 trace.txtEach line represents one memory access:
<r|w> <hex_address>
r= read (load)w= write (store)
Example:
r 00000000
w 00000004
r 0000001c
The simulator prints:
- Configuration summary
- Final cache contents (sets with valid blocks, sorted MRU → LRU, dirty blocks marked
D) - Measurement statistics
Example output (L1 + L2):
===== Simulator configuration =====
BLOCKSIZE: 32
L1_SIZE: 8192
L1_ASSOC: 4
L2_SIZE: 262144
L2_ASSOC: 8
...
===== Measurements =====
a. L1 reads: 161623
b. L1 read misses: 7155
c. L1 writes: 38137
d. L1 write misses: 1149
e. L1 miss rate: 0.0416
f. L1 writebacks: 2132
g. L1 prefetches: 0
h. L2 reads (demand): 8304
i. L2 read misses (demand): 2209
...
q. memory traffic: 4398
- Address decomposition: each address is split into tag, index, and block-offset fields computed from the cache parameters.
- LRU counter scheme: each block stores a recency counter (0 = MRU). On every access, counters are updated so the accessed block becomes 0 and all previously more-recent blocks are aged by 1.
- Writeback on eviction: dirty blocks evicted from L1 trigger a write to L2 (or memory); dirty blocks evicted from L2 go to memory.
- Write-allocate: a write miss allocates a new block by first fetching it from the next level.
- Language: C++ (C++11 compatible)
- Build: GNU Make + g++
- Standard libraries:
<stdio.h>,<stdlib.h>,<cmath>,<vector>,<string>