Pull requests / #2434

#2434 tools: the KV streaming page-pool policy bench - CLOCK against LRFU, LRU and Belady (#2415)

open · @MrKop-git · 0 comments · View on GitHub

BenchmarksDocumentation

Description

## Summary

The measurement-first half of #2415: `tools/replay_kv_stream_policy.py` replays KV block selections through the streaming page pool's policies **offline** and reports misses, hit rate and the bytes re-read over the compulsory load - the same split #1089 reports for the expert cache.

- **Trace**: `int32 layer, int32 k, k block ids, k float32 weights` per resolve call - the `--dump-routing` record layout, so an engine-side `--dump-kv-select` (the follow-up this PR does not add) can write the same shape.
- **CLOCK** is modeled as kv_stream.cu's `resolve_kernel` at slot granularity: reference on use and load, a second-chance sweep from a hand, a slot this call uses never taken, and the kernel's `3*n` scan limit on overflow (`OVERFLOW (too few resident cells)`).
- **LRFU** is ActKV's keep score (`KS = lambda*KS + gain`): the hit range is the top `--top-frac` weight mass of a call with ties at the cut included, decayed every `--decay-every` calls (ActKV decays per compression step, kvmem per request - the cadence is a knob because the right one here is what the sweep finds). **LRU** and **Belady** are the recency baseline and the offline ceiling.
- Five synthetic patterns (scan, loop, agent, intermittent, spotty) stand in until real traces exist.

## What it changes and what it leaves alone

Two `tools/` files and one docs line in DETAILS.md. **The engine and every answer are untouched** - no flag, no kernel, no default.

## How it was checked

`python -m unittest tools.test_replay_kv_stream_policy` - **9 tests**, no GPU, no model pack:

- two hand-worked traces that pin the policies exactly (CLOCK's sweep clearing a resting hot block's reference: 7 misses where LRFU/LRU/Belady make 5; LRFU's keep score keeping a historically hot block LRU ages out: 3 against 4);
- the overflow path (a call that fills the pool terminates like the kernel instead of looping);
- invariants (no policy under the compulsory load; Belady never worse; a scan is all compulsory for everyone);
- a trace round trip and a bad-file refusal.

What the patterns say so far (seed 42, one layer; the parameters are in each line):

| pattern | what it shows |
|---|---|
| `scan` (400 calls, width 100, 1024 slots) | every policy at the 40,000 floor - a scan is all compulsory |
| `spotty` (2000 calls, hot 32 every other call, 8 one-offs, 48 slots) | **CLOCK 8,038 vs the 8,016 floor** - its sweep clears the resting hot set's references between its uses; LRFU/LRU/Belady at the floor |
| `loop` (1000 calls, window 64 over 400 blocks, 128 slots) | all three at 32,032; Belady 25,696 - the churn is structural, only the ceiling does better |
| `intermittent` (1000 calls, hot 32 every call, cold 48 every 8th, 64 slots) | CLOCK = LRFU = Belady at the 2,071 structural floor; **LRU 8,771** - recency ages the hot set out |
| `agent` (2000 calls, tail 96 + task 96 + 16 one-offs, 128 slots) | CLOCK = LRFU = Belady at 216,874; **LRU 414,459** - recency ages the task set out |

So: LRFU is never worse than CLOCK in these patterns and closes its one gap (spotty); the case for making it the default needs real selection traces - which is #2415's engine-side dump follow-up.

## Not tested

Real selection traces (no engine dump exists yet), multi-layer interleavings beyond the `--layers` round-robin, weight-driven hit ranges as the indexer produces them (the synthetic patterns use equal weights), and any link between these miss counts and wall time on a card.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Related on this site

Quick links to related pages.