5.3 KiB
Сборка и 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, а не финальным доказательством.