Files
UniversalContainer/docs/benchmarking.md
T
Efim Beshmenev bbb43dbe57 Experiments
2026-08-11 23:35:38 +03:00

5.3 KiB
Raw Blame History

Сборка и benchmark-методика

Профили кода

Все сравниваемые бинарники — Release x64 /O2, /MT, без IPO/LTO. Отличается только ось SIMD:

Профиль Ключи проекта Назначение
scalar /O2 /d2Qvec- /Qvec-report:1 /Oi- MSVC-specific project-novec
baseline /O2, без /arch:AVX* обычный MSVC x64
avx2 /O2 /arch:AVX2 разрешён AVX2

/d2Qvec- — внутренний, недокументированный ключ MSVC, а не переносимая гарантия. Командная строка проверена автоматическим аудитом для MSVC 19.51; вывод /Qvec-report пока не разбирается как отдельное доказательство. scalar не означает «ни одной SIMD-инструкции в процессе»: x64 ABI имеет SSE2-baseline, а CRT memmove может runtime-dispatch-ить SIMD. Дополнительно задаётся _USE_STD_VECTOR_ALGORITHMS=0, чтобы STL не включала свои явно векторизованные алгоритмы. Это честнее называть project-novec.

Матрица

Benchmark сравнивает:

  • reserved std::vector;
  • std::deque;
  • std::list с index semantics;
  • forced tiered для каждого leaf 64/128/256/512/1024;
  • adaptive deferred;
  • experimental adaptive eager-read.

std::deque и std::list — только внешние фиксированные baselines; AdaptiveSequence никогда в них не переключается. Для std::list runner эмулирует index semantics линейным проходом, поэтому доступ по индексу имеет O(N).

Типы: uint32_t, uint64_t, trivially-copyable 16/32/64-byte значения и non-trivial movable string wrapper. Workloads включают random access, traversal, append, 99.99/99/80/50% reads, uniform/localized edits, bursty edits и отдельный phase trace:

uniform edits -> maintenance
localized edits -> maintenance
reads -> maintenance

Последний trace нужен именно для проверки смены leaf, а не только vector↔tiered. Время rebuild остаётся внутри измеряемого end-to-end интервала.

Tuning перебирает leaf 64…1024 и maximum directory levels 2/3/4. Каталог сам останавливает построение на минимально достаточной глубине.

CSV

Raw CSV содержит profile/type/workload/N/seed, initial и final tier config, total/ns-per-op, p50/p95/p99/max edit latency, checksum, allocated bytes, storage switches, shape rebuilds и final mode. Checksum должен совпасть у всех контейнеров одной трассы.

tools/analyze_results.ps1 сначала берёт median повторов, затем сравнивает с лучшим фиксированным baseline в каждой ячейке. Итоговый geometric mean считается иерархически по sizes → workloads → types → profiles, чтобы семейство с большим числом строк не получило лишний вес.

Масштабы запуска

benchmark.bat smoke   rem проверка всего конвейера
benchmark.bat quick   rem рабочее исследование
benchmark.bat full    rem финальные повторы, длительный запуск

Отдельная large-матрица с обязательным reserved vector, fixed leaf 64…1024 и adaptive запускается внешним process pool. Второй аргумент — число workers:

large_benchmark.bat smoke 12
large_benchmark.bat full 12 3
large_benchmark.bat full 12 3 huge

Каждый worker закрепляется за отдельным logical CPU. Третий аргумент ограничивает число одновременно работающих N=100M-ячеек и лишь снижает риск pagefile; это эвристика, а не измеритель доступной памяти. Четвёртый аргумент huge оставляет только N=100M. Large raw, per-cell partial/log, план, environment и сводки сохраняются в отдельной папке results/benchmarks/.

large_benchmark.bat full 12 3 huge воспроизводит только N=100M с удлинённым 512-edit horizon и сам проверяет поддержку AVX2. Прямой PowerShell runner такой CPU-проверки не выполняет: при его ручном запуске avx2 надо исключить на неподдерживаемой машине.

Для публикации финального числа нужны одинаковый power plan, отсутствие тяжёлой фоновой нагрузки, закрепление на физическом ядре, randomized paired order и holdout workloads/seeds. Текущие quick-данные являются calibration set, а не финальным доказательством.