CP HiCache: redesign owner-lane eviction planner as a lazy-re-evaluation heap (O(n log n))

Replaces the O(victims*candidates) per-iteration greedy argmin rescan in
_plan_cp_load_back_owner_lane_evictions with a leaf-up min-heap. The score
(-contribution, -unlock, slru_priority, node.id) depends on the current deficits, so a
static heap is not equivalent; instead use LAZY RE-EVALUATION: a popped entry is consumed
only if its score still matches the node's current score (deficits unchanged since push),
else it is re-pushed with the fresh score. Stale scores are always optimistic (contribution
= sum(min(counts[o], deficits[o])) and the ancestor-unlock contribution only shrink as
deficits shrink), so the first up-to-date popped entry is exactly the global argmin the full
rescan would have picked -> PROVABLY EQUIVALENT, with the same leaf-up eligibility +
ancestor-unlock + parent-push. Determinism/rank-uniformity preserved (selection decided by
the total-ordered score; the heap insertion seq only orders structurally-equal tuples).

Equivalence proven by test: a verbatim reference greedy + a randomized property test (300
seeds, single- AND multi-owner deficits, non-uniform counts exercising the lazy-re-eval
boundary, varied SLRU priorities) asserting byte-identical (victims, planned_freed,
remaining), plus an explicit leaf-up + ancestor-unlock case (child-then-parent). 14 planner
tests pass (1 pre-existing unrelated EAGLE-tail failure unchanged).

Micro-bench (V100, candidates=2000 deficit=7877, benchmark/hicache/bench_cp_owner_lane_planner.py):
  A. ORIGINAL (.item() x cp, no memo)   50.06s
  B. memo + bincount (greedy)            0.494s   (101x)
  C. lazy-re-eval heap                   0.162s   (309x; 3.0x over B)   selection A==B==C identical

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-24 01:35:37 +00:00
co-authored by Claude Opus 4.8
parent 2e15cb257a
commit fdc23f7d61
3 changed files with 297 additions and 102 deletions
@@ -88,29 +88,54 @@ def plan_greedy(counts_fn, use_memo):
def plan_heap(counts_fn):
"""Redesign (single-owner deficit): compute counts once, sort by -counts[owner], one pass.
Byte-identical victim SET to greedy for a single-owner deficit (highest owner-count first,
id tiebreak) -- the contribution is min(counts[owner], remaining) == counts[owner] until the
final pick."""
owner = DEFICIT_OWNER
scored = []
for nid, value in NODES:
counts = counts_fn(value)
if counts[owner] <= 0:
continue
scored.append((counts, nid))
scored.sort(key=lambda x: (-x[0][owner], x[1]))
rem = [0] * CP
rem[owner] = DEFICIT
"""The SHIPPED heap redesign: lazy-re-evaluation min-heap (a popped entry is used only if
its score is still current, else re-pushed). Provably equivalent to the greedy argmin
rescan; here flat (no tree) so it isolates the algorithmic cost vs B."""
import heapq
deficits = [0] * CP
deficits[DEFICIT_OWNER] = DEFICIT
planned_evicted = set()
planned_freed = [0] * CP
memo = {}
heap = []
seq = 0
def scored(nid, value):
if nid in memo:
counts = memo[nid]
else:
counts = counts_fn(value)
memo[nid] = counts
contribution = sum(min(c, d) for c, d in zip(counts, deficits))
if contribution <= 0:
return None
return (-contribution, nid), counts
for nid, value in NODES:
s = scored(nid, value)
if s is not None:
heapq.heappush(heap, (s[0], seq, nid, s[1]))
seq += 1
victims = 0
for counts, nid in scored:
if all(v <= 0 for v in rem):
break
while any(v > 0 for v in deficits) and heap:
score, _s, nid, counts = heapq.heappop(heap)
if nid in planned_evicted:
continue
fresh = scored(nid, None) # counts already memoized
if fresh is None:
continue
if fresh[0] != score:
heapq.heappush(heap, (fresh[0], seq, nid, fresh[1]))
seq += 1
continue
counts = fresh[1]
planned_evicted.add(nid)
victims += 1
for o, c in enumerate(counts):
planned_freed[o] += c
rem[o] = max(0, rem[o] - c)
victims += 1
deficits[o] = max(0, deficits[o] - c)
return victims, tuple(planned_freed)
@@ -133,7 +158,7 @@ def main():
vO, fO = timed("A. ORIGINAL (.item() x cp, no memo)", lambda: plan_greedy(counts_original, False))
vF, fF = timed("B. FIXED (bincount + per-plan memo)", lambda: plan_greedy(counts_fixed, True))
vH, fH = timed("C. REDESIGN (counts-once + sorted pass)", lambda: plan_heap(counts_fixed))
vH, fH = timed("C. REDESIGN (lazy-re-eval heap)", lambda: plan_heap(counts_fixed))
print("\nselection identical (victims, planned_freed):")
print(f" A==B: {(vO, fO) == (vF, fF)} A==C: {(vO, fO) == (vH, fH)}")