# Сборка и 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: ```text 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, чтобы семейство с большим числом строк не получило лишний вес. ## Масштабы запуска ```bat benchmark.bat smoke rem проверка всего конвейера benchmark.bat quick rem рабочее исследование benchmark.bat full rem финальные повторы, длительный запуск ``` Отдельная large-матрица с обязательным reserved vector, fixed leaf 64…1024 и adaptive запускается внешним process pool. Второй аргумент — число workers: ```bat 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, а не финальным доказательством.