CAFS: A Cache-Aware Frequency Sort for Low-Cardinality Integer Data on x86-64
Abstract
Integer sorts in OLAP engines often run on columns whose cardinality is much smaller than the array length . After a group-by stage the intermediate key column has bounded by the number of distinct group keys, and even a column-store scan typically operates on dictionary-encoded categorical fields where never exceeds a few thousand. A comparison sort on such a column still pays comparisons, and a radix sort still pays byte passes, irrespective of . This paper describes CAFS, an integer sort that does exploit it on x86-64 with AVX2. The algorithm combines a SIMD bucket sized to one cache line, a Chao1 cardinality estimator over 1024 strided samples (kept in a heap-allocated 40 KB open-addressing table), and an adaptive dispatcher backed by a spill safety guard. The hot loop is branchless and uses AVX2 cmpeq together with movemask and tzcnt to locate the matching lane. We benchmarked CAFS on a full-factorial grid of 58 array sizes from to with dense schedules per , producing 592770 timed runs against pdqsort, IPS4o, vqsort, ska_sort, and std::sort. In the band the throughput is 1.7 to 3.1x that of pdqsort, 1.7 to 3.5x IPS4o, and 1.2 to 2.3x vqsort. The operational crossover against pdqsort is at ; against ska_sort, ; against vqsort, ; and against IPS4o the curves only converge near . Of the five baselines, only vqsort actually overtakes CAFS once the crossover is passed, which makes the vqsort threshold at the binding constraint on the operational range of CAFS.
Cite
@article{arxiv.2605.25040,
title = {CAFS: A Cache-Aware Frequency Sort for Low-Cardinality Integer Data on x86-64},
author = {Vasiliy S. Shlyk},
journal= {arXiv preprint arXiv:2605.25040},
year = {2026}
}
Comments
28 pages, 15 figures, 10 tables. Source code: https://github.com/kexibq-official/cafs-lib