# How to Consider Object Size Distributions in libCacheSim Simulations: A Complete Guide

> Learn how to consider object size distributions in libCacheSim simulations using request_t.obj_size and ignore_obj_size for statistical analysis and byte-aware caching.

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

---

**libCacheSim natively supports object size distributions through the `request_t.obj_size` field, enabling both statistical trace analysis and byte-aware cache simulations via the `ignore_obj_size` configuration flag.**

libCacheSim is a high-performance caching simulator designed for realistic workload modeling. The framework treats object size as a first-class attribute, allowing researchers to analyze size distributions in traces and run simulations that account for byte-level capacity constraints rather than simple object counts.

## Where Object Size is Captured

libCacheSim captures size information at the trace parsing layer and propagates it through every simulation stage.

### The request_t Structure

Every memory request in libCacheSim is represented by `request_t`, defined in [`libCacheSim/include/libCacheSim/request.h`](https://github.com/1a1a11a/libcachesim/blob/main/libCacheSim/include/libCacheSim/request.h). This structure contains the `obj_size` field, which stores the byte size of each requested object. Trace readers populate this field during log ingestion:

- **CSV traces**: Parsed in [`libCacheSim/traceReader/csv.c`](https://github.com/1a1a11a/libcachesim/blob/main/libCacheSim/traceReader/csv.c) at line 236
- **Binary LCS format**: Parsed in [`libCacheSim/traceReader/customizedReader/lcs.c`](https://github.com/1a1a11a/libcachesim/blob/main/libCacheSim/traceReader/customizedReader/lcs.c) at line 167

### The ignore_obj_size Toggle

You can force unit-size behavior by setting the `ignore_obj_size` flag in `reader_t`. In [`libCacheSim/traceReader/reader.c`](https://github.com/1a1a11a/libcachesim/blob/main/libCacheSim/traceReader/reader.c) (lines 332-333), this boolean flag defaults to `false`, but when enabled, it forces `req->obj_size = 1` for every request. This is useful when comparing size-aware versus size-agnostic policy performance on identical request sequences.

## Analyzing Size Distributions

libCacheSim provides dedicated tooling for statistical analysis of object size distributions before running simulations.

### Generating Distribution Statistics

Run `traceAnalyzer` with the `--size` task to produce CDF data files:

```bash
./bin/traceAnalyzer path/to/trace LCS_TRACE --size

```

This generates `*.size.req` (request-weighted) and `*.size.obj` (object-weighted) distribution files. The C++ core writes raw counters in [`libCacheSim/traceReader/customizedReader/lcs.c`](https://github.com/1a1a11a/libcachesim/blob/main/libCacheSim/traceReader/customizedReader/lcs.c), including the smallest and largest sizes (lines 56-57) and most-common size lists (lines 61-68).

### Visualizing with Python

Two scripts process these statistics:

**[`scripts/traceAnalysis/size.py`](https://github.com/1a1a11a/libcachesim/blob/main/scripts/traceAnalysis/size.py)** loads CDF dictionaries (`obj_size_req_cnt`, `obj_size_obj_cnt`) via `_load_size_data()` (lines 40-64) and generates log-scaled plots through `plot_size_distribution()` (lines 70-99).

**[`scripts/traceAnalysis/size_heatmap.py`](https://github.com/1a1a11a/libcachesim/blob/main/scripts/traceAnalysis/size_heatmap.py)** creates time-vs-size heatmaps using `load_size_window_data()`, requiring traces with wall-clock timestamps.

Both tools are documented in [`doc/quickstart_traceAnalyzer.md`](https://github.com/1a1a11a/libcachesim/blob/main/doc/quickstart_traceAnalyzer.md) (lines 27-31 and 98-104).

## Size-Aware Cache Simulation

Cache algorithms receive `request_t *req` pointers and can inspect `req->obj_size` to make eviction decisions based on byte capacity rather than object count.

### Byte-Based Eviction Policies

Size-sensitive policies compare `req->obj_size + cache->obj_md_size` against the cache's byte capacity:

- **Size policy**: Checks capacity in [`libCacheSim/cache/eviction/Size.c`](https://github.com/1a1a11a/libcachesim/blob/main/libCacheSim/cache/eviction/Size.c) at line 146
- **WTinyLFU**: Accounts for metadata overhead in [`libCacheSim/cache/eviction/WTinyLFU.c`](https://github.com/1a1a11a/libcachesim/blob/main/libCacheSim/cache/eviction/WTinyLFU.c) (lines 279-287)
- **SFIFO**: Handles size constraints in [`libCacheSim/cache/eviction/fifo/SFIFO.c`](https://github.com/1a1a11a/libcachesim/blob/main/libCacheSim/cache/eviction/fifo/SFIFO.c) at line 225

Traditional LRU/LFU policies that count objects ignore size unless explicitly modified, as seen in [`flashProb.c`](https://github.com/1a1a11a/libcachesim/blob/main/flashProb.c) at line 252.

### Miss Ratio Calculations

When `ignore_obj_size` is false, the simulator computes byte miss ratios (`n_miss_byte` in [`profiler/simulator.c`](https://github.com/1a1a11a/libcachesim/blob/main/profiler/simulator.c) at line 104). When enabled, simulations report only request-count miss ratios, fundamentally changing performance metrics for workloads with heterogeneous object sizes.

## Configuration Pipeline

Follow this workflow to incorporate size distributions into your analysis:

1. **Analyze the trace**: Generate size statistics with `./bin/traceAnalyzer path/to/trace LCS_TRACE --size`
2. **Plot distributions**: Run `python3 scripts/traceAnalysis/size.py trace.size` to create `trace_size.svg` and `trace_size_log.svg`
3. **Generate heatmaps**: Execute `python3 scripts/traceAnalysis/size_heatmap.py trace.sizeWindow_w300` for time-varying size analysis
4. **Run byte-aware simulation**: Use `./bin/simulator -c myCache.conf -t path/to/trace LCS_TRACE` with `cache_size` specified in bytes
5. **Compare with object counts**: Add `--ignore-obj-size` to force `obj_size = 1` for all requests

## When to Consider Object Size

Enable size-aware simulation for these workload types:

- **Key-value stores**: Where object bytes vary widely (e.g., storage services). Use size-aware policies and CDF plots to understand large-object tails.
- **Block-level caches**: For fixed-size blocks (SSD/flash), set `ignore_obj_size = true` to treat all blocks equally.
- **Algorithm research**: Toggle `ignore_obj_size` to isolate the impact of size distribution on policy performance while keeping request sequences identical.

## Code Examples

### Extracting and Plotting Size Distributions

```bash

# Generate size statistics

./bin/traceAnalyzer data/twitter_cluster52_10m.csv CSV_TRACE --size

# Create CDF plots (generates both request and object weighted curves)

python3 scripts/traceAnalysis/size.py data/twitter_cluster52_10m.size

```

Output files: `data/twitter_cluster52_10m_size.svg` and `data/twitter_cluster52_10m_size_log.svg`.

### Running Byte-Aware Simulations

```bash

# Configure cache_size in bytes (e.g., 1GiB) in myCache.conf

./bin/simulator -c config/cache.conf -t data/twitter_cluster52_10m.csv CSV_TRACE

```

The simulator reads `obj_size` from each request (see [`libCacheSim/traceReader/reader.c`](https://github.com/1a1a11a/libcachesim/blob/main/libCacheSim/traceReader/reader.c) at line 332) and reports byte miss ratios.

### Disabling Size Considerations

```bash

# Force unit size for all requests

./bin/simulator -c config/cache.conf -t data/twitter_cluster52_10m.csv CSV_TRACE \
    --ignore-obj-size

```

This sets `reader->ignore_obj_size = true` (lines 332-333 in [`reader.c`](https://github.com/1a1a11a/libcachesim/blob/main/reader.c)), yielding pure object-count miss ratios.

## Key Files Reference

- **[`libCacheSim/include/libCacheSim/request.h`](https://github.com/1a1a11a/libcachesim/blob/main/libCacheSim/include/libCacheSim/request.h)**: Defines `request_t` with `obj_size` field
- **[`libCacheSim/traceReader/reader.c`](https://github.com/1a1a11a/libcachesim/blob/main/libCacheSim/traceReader/reader.c)**: Core reader logic and `ignore_obj_size` handling (lines 332-333)
- **[`libCacheSim/traceReader/customizedReader/lcs.c`](https://github.com/1a1a11a/libcachesim/blob/main/libCacheSim/traceReader/customizedReader/lcs.c)**: Statistics printing for smallest/largest sizes (lines 56-68)
- **[`scripts/traceAnalysis/size.py`](https://github.com/1a1a11a/libcachesim/blob/main/scripts/traceAnalysis/size.py)**: CDF plotting functions `_load_size_data()` and `plot_size_distribution()`
- **[`scripts/traceAnalysis/size_heatmap.py`](https://github.com/1a1a11a/libcachesim/blob/main/scripts/traceAnalysis/size_heatmap.py)**: Time-varying size visualization
- **[`libCacheSim/cache/eviction/Size.c`](https://github.com/1a1a11a/libcachesim/blob/main/libCacheSim/cache/eviction/Size.c)**: Example size-aware policy implementation (line 146)
- **[`doc/quickstart_traceAnalyzer.md`](https://github.com/1a1a11a/libcachesim/blob/main/doc/quickstart_traceAnalyzer.md)**: User guide for size analysis tasks

These files demonstrate how libCacheSim captures object sizes, produces distribution statistics, and enables byte-accurate cache simulations.

## Summary

- libCacheSim stores object sizes in `request_t.obj_size`, populated by trace readers in [`csv.c`](https://github.com/1a1a11a/libcachesim/blob/main/csv.c) and [`lcs.c`](https://github.com/1a1a11a/libcachesim/blob/main/lcs.c)
- Set `ignore_obj_size = true` in `reader_init_param_t` to force unit-size behavior for object-count simulations
- Use `traceAnalyzer --size` and [`scripts/traceAnalysis/size.py`](https://github.com/1a1a11a/libcachesim/blob/main/scripts/traceAnalysis/size.py) to generate CDF plots of size distributions
- Byte-aware policies like Size and WTinyLFU reference `req->obj_size` for capacity management in [`Size.c`](https://github.com/1a1a11a/libcachesim/blob/main/Size.c) and [`WTinyLFU.c`](https://github.com/1a1a11a/libcachesim/blob/main/WTinyLFU.c)
- The simulator reports byte miss ratios (`n_miss_byte`) when size is enabled, or request counts when disabled

## Frequently Asked Questions

### How do I force all objects to size 1 in libCacheSim?

Set the `ignore_obj_size` parameter to `true` either in the `reader_init_param_t` structure or via the `--ignore-obj-size` CLI flag. This forces `req->obj_size = 1` for every request (see [`libCacheSim/traceReader/reader.c`](https://github.com/1a1a11a/libcachesim/blob/main/libCacheSim/traceReader/reader.c) lines 332-333), converting byte-aware simulations into pure object-count analyses.

### Which eviction policies support object size awareness?

Byte-aware policies include **Size**, **WTinyLFU**, and **SFIFO**, which check `req->obj_size + cache->obj_md_size` against byte capacity in [`Size.c`](https://github.com/1a1a11a/libcachesim/blob/main/Size.c) (line 146) and [`WTinyLFU.c`](https://github.com/1a1a11a/libcachesim/blob/main/WTinyLFU.c) (lines 279-287). Traditional LRU and LFU count objects unless explicitly modified to inspect `obj_size`.

### How do I visualize object size distributions from my trace?

Run `./bin/traceAnalyzer` with the `--size` flag to generate `*.size` files, then process them with `python3 scripts/traceAnalysis/size.py`. This creates SVG plots showing both request-weighted and object-weighted CDFs on linear and log scales.

### What is the difference between byte miss ratio and object miss ratio?

Byte miss ratio (`n_miss_byte` in [`profiler/simulator.c`](https://github.com/1a1a11a/libcachesim/blob/main/profiler/simulator.c)) weights each miss by the object's size, while object miss ratio counts each miss equally. When `ignore_obj_size` is enabled, only object miss ratios are reported. For heterogeneous workloads (e.g., key-value stores), byte miss ratio often better represents cache efficiency.