cache-miss-analyzer

Valid-Checking LRU — a preallocated block management approach


The Valid-Checking LRU (Least Recently Used) cache is a set-associative cache implementation that pre-allocates all cache blocks at initialization. Unlike dynamically allocated caches, this approach marks blocks as valid=false when they are not in use.


Features



Implementation Details




Step-by-Step Explanation

Initial State

Empty but Preallocated Blocks.

Unlike Dynamic-Way LRU, all blocks are initialized with valid=false at the start.

0


First Access: A1115550

Miss! But there are still invalid blocks available.

Instead of evicting, use an invalid block.

Mark it valid=true and move it to the front.

0


Second Access: A1115551

Miss! But still, there are invalid blocks available.

Use an invalid block, mark it valid, move it to the front.

0


Third Access - A1115550

Hit! A1115550 is already in the set.

Move it to the front (most recently used).

0


Filling Up the Set (Set is Full)

After accessing A1115552 and A1115553, the set is full.

Every block is now valid=true, so next miss must trigger an eviction.

0


Access A1115560 (Eviction required)

Miss! No invalid blocks remain.

Evict LRU block (A1115551, closest to Dummy Tail).

Replace it with A1115560 and move to the front.

0


Another Hit – A1115550

Hit! A1115550 is in the set.

Move it to the front (MRU).

0


Time Complexity Analysis

Lookup (Hit/Miss Checking)


Insert New Block (On Miss)

Two scenarios for handling a miss:

  1. Use an invalid block: O(N), worst-case requires searching all set entries.
  2. Evict LRU block (if all are valid): O(1).

Case 1: Use an invalid block Search for a valid=false block: O(N) (N = set_degree, worst case is that all blocks are valid). Update block’s tag and set valid=true: O(1). Move block to head (most recently used): O(1).

Overall: O(N) + O(1) + O(1) = O(N) (Worst case: scanning all blocks in the set to find an invalid one.)


Case 2: Evict LRU block (All blocks are valid=true) Find LRU block (always at the tail): O(1). Replace with new block, update tag, set valid=true: O(1). Move to head (most recently used): O(1).

Overall: O(1) + O(1) + O(1) = O(1)


Move Block to Head (On Hit)

Overall: O(1) + O(1) + O(1) = O(1).


Eviction (When the set is full)

Overall: O(1) + O(1) + O(1) + O(1) = O(1).


Summary

Operation Complexity
Lookup O(1)
Insert O(N)
Move to Head O(1)
Eviction O(1)


Overall Complexity: O(N).



Getting Started

Prerequisites

Building and Running

Clone the repository

git clone https://github.com/mellivorandy/cache-miss-analyzer.git


From the project root, run:

cargo build


To execute the program with custom arguments, use the following command:

cargo run -p valid_checking_lru -- <trace_file_name> <cache_size> <block_size> <set_degree>


In this project structure, the trace.txt file is located in cache-miss-analyzer/data, change the path if the trace file is moved or new trace files are added.


Note: If the file path remains unchanged, use the path as given. Simply copy and paste the following command into your terminal:

Example command

cargo run -p valid_checking_lru -- ./data/trace.txt 128 4 1



Test

A [cfg(test)] test module is included, referencing a trace.txt file for unit tests. To run them:

cargo test -p valid_checking_lru -- --nocapture

This prints the non-empty sets.



Acknowledgments

I sincerely appreciate the incredible work behind Mermaid.js, an open-source diagramming tool that makes visualizing complex ideas effortless. Huge thanks to the developers and contributors who maintain and improve this fantastic project!