Repository navigation
Conversation
Slab.Lookup takes a tally argument. When it is set, a lookup that finds its key adds one to a counter in the slot of the Readers that it pinned the node with, which is in the cache line that a reader writes to anyway. Readers.Hits adds the counters up. Unlike the Meta of a node, the tally knows no limit, so a cache can tell how many requests its readers answered without their writing to anything that all of them share. s3fifo and sieve do not tally. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
internal/sketch is the count-min sketch of TinyLFU in Caffeine's layout: four 4-bit counters per key, in four words of one 64-byte block, sixteen counters to a word and a word for every entry of the cache. Counters stop at fifteen and are halved, with the tally of what they have counted, whenever that tally reaches the sample. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A new entry waits in a small queue, as in S3-FIFO. When its turn comes it gets into the main queue only if the sketch has its key down as asked for more often of late than the entry that the main queue would evict next; otherwise it goes. The main queue gives an entry that was read another round, up to three in a row. Reads take no lock: they count on the entry up to three, and the next write that comes by the entry tells the sketch, which only writers touch. The size of the small queue is found by Caffeine's hill climber, one for the whole cache. It goes by the share of requests answered, counted exactly: readers tally their hits in their slots, and shards hand on their misses, in batches when there are several of them. It starts at a hundredth of the room and stays between that and four fifths. The cache is compared step by step with a model of the policy, fuzzed against it, and checked under the race detector, also while the window moves and Clear runs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tinylfu joins the caches of the benchmarks, as one whose hit ratio varies from one replay to the next like otter's: its sketch has keys share counters by a hash that is seeded at random. The reports are made again for all caches, and the README and the docs that quote them follow the new numbers. On the eleven traces tinylfu answers 47.9% of the requests on average, otter 47.5% and s3fifo 44.8%, and tinylfu is never more than 5.3 points behind the best cache. The README now suggests it if in doubt, with what speaks against it: it was designed on these traces, it varies between runs, it is up to four points behind lru on Mixed at its larger capacities, and with eight CPUs and 1% writes it was 22% slower than s3fifo, which has not been explained. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A fifth cache,
tinylfu. A new entry waits in a small queue, as in S3-FIFO. When its turn comes, it gets into the main queue only if a frequency sketch has its key down as asked for more often of late than the entry that the main queue would evict next. The main queue gives an entry that was read another round, up to three in a row. The size of the small queue is found by Caffeine's hill climber.Reads take no lock, as in
s3fifoandsieve:Commits
internal/cslab:Lookupcan tally hits in the reader's slot;Readers.Hitsadds them up.s3fifoandsievepassfalse.internal/sketch: the count-min sketch of TinyLFU in Caffeine's layout.tinylfu: the cache, the climber, a reference model, scenario tests, a fuzz target, and a load test of the climber under the race detector.bench:tinylfujoins the benchmarks, and all reports are made again; README and the docs that quote them follow the new numbers.Results (bench/results, Apple M3 Max)
tinylfus3fifotinylfuis ahead of otter on every replay in 42 rows and behind in 14.s3fifoat 1, 2 and 8 CPUs, and reads through faster with 8, because it misses less.s3fifo.s3fifo, and it gives the garbage collector just as little to do.What speaks against it, all in the README:
lru.lru(6.6% against 66.7% in a synthetic test).s3fifo. Taking out everything it does differently on that path did not close the gap, and the cause has not been found.The README now says "If in doubt, use
tinylfu" (it saids3fifo).s3fifostays the advice for the same results on every run and for workloads without loops.Checked
make lint,make test(race detector),go vetand test compilation for linux/386; every commit builds and passes on its own.Clearwithout the window's lock, is caught by the race detector.Clearwith batched shards; fixed, and tested.🤖 Generated with Claude Code