8.6 KiB
Сборка и benchmark-методика
Активная focused-постановка
Текущий benchmark отвечает на один практический вопрос: при каком N для
фиксированной малой доли правок становится выгодно переходить от contiguous
vector к tiered storage. Старую широкую матрицу типов, SIMD-профилей, leaf и
workload для этой калибровки не используют.
Все три кандидата имеют один и тот же тип данных и один и тот же flat hash:
| Имя в CSV | Реализация | Режим |
|---|---|---|
forced_vector_hash |
AdaptiveSequence<uint32_t, true> |
принудительно vector |
forced_tiered_hash |
AdaptiveSequence<uint32_t, true> |
принудительно tiered |
adaptive_hash |
AdaptiveSequence<uint32_t, true> |
текущая resize-bound auto-policy |
Таким образом, поиск по значению не даёт одному кандидату скрытого преимущества:
стоимость хранения и обновления hash index присутствует у vector, tiered и
adaptive. Для forced tiered начальный leaf равен ceil(sqrt(N)). Auto-mode
выбирает mode и leaf только при capacity-boundary.
Трасса
Mixed trace содержит ровно 100000 операций в default-запуске:
| Операция | Доля | Default count | Детали |
|---|---|---|---|
| индексное чтение | 97% | 97000 | случайный существующий индекс |
| hash find по значению | 1% | 1000 | find_one, 50% hit / 50% miss |
| вставка | 1% | 1000 | случайная позиция |
| удаление | 1% | 1000 | случайная существующая позиция |
Виды операций перемешиваются детерминированным seed. Вставки и удаления сбалансированы, поэтому benchmark измеряет steady-size workload, но любая реально достигнутая capacity-boundary и стоимость перехода остаются внутри mixed timer. Построение исходного контейнера находится вне timer.
Кроме общей mixed ops/s, runner измеряет отдельные homogeneous batches и
выводит read ops/s, find ops/s, insert ops/s, erase ops/s. Быстрые read
и find batches содержат не менее 100000 вызовов для устойчивости таймера;
фактические batch counts записываются в CSV. Поэтому отдельные колонки — это
пропускная способность соответствующего типа операции, а не время его 1%-доли
в mixed trace.
Один и тот же материализованный trace и seed применяются к трём кандидатам. Порядок кандидатов циклически меняется между paired repeats, чтобы фиксированная первая или последняя позиция не принадлежала всегда одному представлению. Checksum проверяет совпадение состояния и результатов операций.
Capacity, leaf и hash во время измерения
Focused benchmark проверяет текущий контракт контейнера, а не внешнюю эмуляцию:
- capacity увеличивается
x2, когда очередная вставка не помещается; - при
size <= capacity / 8выполняется один shrink-шагcapacity / 2; - mode и
leaf = ceil(sqrt(size))пересчитываются только внутри этой capacity-перестройки; - focused cutoff auto-mode равен 4096;
- hash buckets рассчитываются из новой логической capacity с worst-case load не выше 70% и не меняются независимо между capacity-boundaries.
Raw CSV сохраняет initial/final mode, leaf и logical capacity mixed-контейнера,
что позволяет увидеть включённый в mixed throughput переход vector -> tiered
или обратный переход. Для четырёх отдельных homogeneous batches поля
read_mode, find_mode, insert_mode, erase_mode и соответствующие
*_leaf отдельно фиксируют их фактический режим/геометрию; эти batches
стартуют с новых контейнеров и потому не обязаны повторять final mode/leaf
mixed-трассы.
Воспроизводимый default-run
Из обычной командной строки Windows:
benchmark.bat
Скрипт выполняет ровно один focused-run:
build.bat baseline test— Release x64/O2,/MT, без/arch:AVX*и без IPO/LTO, затем correctness-тесты.- Создаёт
results\benchmarks\<timestamp>-focused\и записывает metadata и source/binary manifests. - Запускает
uc_focused_benchдля степеней двойкиN=256...65536, 100000 mixed operations и 7 paired repeats. - Печатает таблицу медиан operations/second, сохраняет её в
summary.md, а raw repeat data — вbaseline-focused.csv.
Эквивалентный вызов runner после сборки:
out\bin\baseline\Release\uc_focused_bench.exe --min-n 256 --max-n 65536 --operations 100000 --repeats 7 --output results\benchmarks\focused.csv
--operations должен быть положительным числом, кратным 100. Доступны также
--seed, --min-n и --max-n; границы диапазона округляются до степеней
двойки.
Финальную таблицу следует публиковать в каталоге соответствующего запуска в
results/benchmarks/. Документация хранит только постановку и подтверждённые
выводы, а не копию ещё незавершённой серии.
CSV
Каждая raw-строка содержит:
profile,n,container,repeat,seed;- initial/final mixed
mode,leaf,logical_capacityи отдельные mode/leaf поля read/find/insert/erase batches; - mixed counts, включая hit/miss hash find;
- реальные размеры отдельных read/find/insert/erase batches;
mixed_ops_per_sec,read_ops_per_sec,find_ops_per_sec,insert_ops_per_sec,erase_ops_per_sec;- оценку allocated bytes и checksum.
Публикуемая таблица использует медиану семи повторов по каждой паре
(N, container). Значения отдельных повторов не отбрасываются и остаются в
raw CSV.
Historical / retired benchmark matrix
Старый uc_bench, вызовы benchmark.bat smoke|quick|full, multi-profile
сравнение scalar/baseline/avx2, типы от uint32_t до blob/string wrapper,
fixed leaf 64...1024, std::deque, std::list, phase traces и
large_benchmark.bat до N=100M относятся к historical / retired методике.
Их CSV сохранены для аудита истории проекта, но не участвуют в выборе текущего cutoff: набор кандидатов, mix операций и наличие hash index отличаются от focused постановки. Старые aggregate scores и speedup нельзя смешивать с новой таблицей operations/second.
Профили scalar и avx2 по-прежнему можно собирать для отдельных инженерных
экспериментов. scalar использует внутренний MSVC /d2Qvec- и не является
универсальной гарантией отсутствия SIMD в CRT/ABI; это ещё одна причина не
расширять текущий baseline-run до старой матрицы без отдельной задачи.