# Large-scale исследование: fixed tiered, adaptive и vector Статус: exploratory throughput study с 12-worker pool; для N=100M одновременно работали не более трёх процессов. Это эвристически снижало риск pagefile на машине с 32 GiB RAM, но RSS/page faults отдельно не измерялись. Это основной отчёт для серий [`20260811-large-full-12c-v1`](../20260811-large-full-12c-v1/) и текущего seed-jittered holdout `v2`. ## Что измерено - Ryzen 9 5900X, 32 GiB RAM, MSVC 19.51, Windows build 26200. - Release x64 `/O2`, статический runtime `/MT`, без IPO/LTO. - Профили `scalar` (`project-novec`), обычный `baseline` и `/arch:AVX2`. - `uint32_t`, размеры от 100 тысяч до 100 миллионов элементов. - В каждой ячейке один и тот же материализованный trace для семи кандидатов: reserved `std::vector`, forced tiered с leaf 64/128/256/512/1024 и `adaptive_shape_deferred`. - Плотность правок: 0%, 0.01%, 0.1%, 1%, 5%, 20%, 50% и 100%; отдельно локализованные, bursty и phase-сценарии. - `v1` использует короткий горизонт 256 правок при N=100M и периодическое размещение steady-правок. `v2` исправляет методический alias: 512 правок размещаются seed-зависимой выборкой с точным общим количеством. Все коэффициенты ниже — `время кандидата / время лучшего fixed-tiered`. Значение больше единицы означает проигрыш кандидата. ## Масштабирование | Серия | N | Adaptive / best fixed | Vector / best fixed | Adaptive / vector | Adaptive победил fixed | |---|---:|---:|---:|---:|---:| | v1 | 100K | 1.425x | 1.342x | 1.062x | 18/42 | | v1 | 1M | 17.75x | 30.98x | 0.573x | 6/42 | | v1 | 10M | 133.82x | 177.07x | 0.756x | 3/42 | | v1, короткий horizon | 100M | 621.77x | 559.89x | 1.111x | 3/42 | | v2, seed-jittered | 100M | 379.28x | 572.36x | 0.663x | 3/42 | Геометрическое среднее берётся по workload и трём профилям. Строки v1 и v2 при N=100M не являются парным сравнением: у них намеренно различаются horizon и временное размещение правок. ## N=100M: зависимость от плотности | Сценарий | Правок | Лучший leaf | Adaptive / fixed | Vector / fixed | Adaptive / vector | Итог adaptive | |---|---:|---:|---:|---:|---:|---| | steady uniform | 0% | 1024 | 0.115x | 0.095x | 1.212x | остаётся vector | | steady uniform | 0.01% | 512 | 7.46x | 7.19x | 1.037x | остаётся vector | | steady uniform | 0.1% | 128 | 50.58x | 58.51x | 0.864x | остаётся vector | | steady uniform | 1% | 1024 | 379.88x | 437.19x | 0.869x | остаётся vector | | steady uniform | 5% | 128 | 438.56x | 1317.81x | 0.333x | 1 switch -> leaf1024 | | steady uniform | 20% | 1024 | 1700.61x | 4736.79x | 0.359x | 1 switch -> leaf1024 | | steady uniform | 50% | 256 | 6626.61x | 10059.97x | 0.659x | 1 switch -> leaf1024 | | steady uniform | 100% | 256 | 7145.17x | 11632.45x | 0.614x | 1 switch -> leaf1024 | | steady localized | 0.1% | 256 | 76.05x | 78.99x | 0.963x | остаётся vector | | steady localized | 1% | 128 | 583.65x | 521.20x | 1.120x | остаётся vector | | steady localized | 20% | 256 | 2828.02x | 6551.50x | 0.432x | 1 switch -> leaf1024 | | steady localized | 100% | 64 | 13819.58x | 21605.68x | 0.640x | 1 switch -> leaf1024 | | bursty uniform | 1% | 1024 | 245.92x | 672.61x | 0.366x | 1 switch -> leaf1024 | | uniform -> localized -> reads | 20% | 512 | 5150.01x | 8124.41x | 0.634x | поздний switch -> leaf1024 | ## Fixed leaf и накладные расходы Ни один leaf не является универсальным. В 42 profile/workload-ячейках v2 победители распределились так: leaf512 — 31.0%, leaf1024 — 26.2%, leaf256 — 23.8%, leaf128 — 14.3%, leaf64 — 4.8%. Локализованные 100%-правки выбрали leaf64, а чистое чтение — leaf1024. Среднее наблюдаемое время построения N=100M: vector 0.171 s, adaptive 0.765 s, forced tiered 1.61–1.89 s. Финальный учтённый объём: vector 0.419 GiB, adaptive в среднем 0.671 GiB, fixed tiered 0.860–0.989 GiB. Это не peak RSS: временная копия при конверсии в эту колонку не входит. Наблюдаемый переход adaptive занимал 0.788–1.284 s под совместной нагрузкой трёх N=100M-процессов. В измеренном бинарнике конструктор benchmark-адаптера vector сначала копировал данные, а затем переносил их при `reserve`; после серии harness исправлен на reserve-before-copy. На `ns/op` это не влияло, но 0.171 s следует считать верхней оценкой старого construction path, а не чистой ценой построения vector. ## Вывод На этой матрице fixed tiered действительно лучше текущего adaptive для любого устойчивого ненулевого потока middle insert/erase при N=100M. Исключение — чистое чтение: vector примерно в 10.5 раза, а adaptive в 8.7 раза быстрее лучшего forced-tiered. Adaptive уже полезнее голого vector: после перехода он выигрывает у vector в 1.5–3 раза на плотных и bursty-трассах. Но он слишком долго накапливает evidence в vector, успевает заплатить за сотни O(N)-сдвигов и всегда выбирает leaf1024, хотя oracle часто выбирает 64–512. Поэтому его основной проигрыш — не стоимость tiered hot path, а поздний первый переход и недостаточно чувствительное правило выбора geometry. Следующая версия policy должна накапливать фактический regret в наносекундах, масштабировать решение с N и стоимостью наблюдаемых сдвигов, а не ждать почти фиксированную долю/число операций. Pending-переход также надо отменять после смены фазы, если будущая экономия уже исчезла. Для выбора leaf нужны отдельные сигналы локальности и плотности: единый leaf1024 здесь явно не является приемлемым ответом. ## Ограничения - Это co-scheduled throughput: pool имеет 12 закреплённых workers, а N=100M выполнялся по три процесса одновременно; они всё равно делят L3 и память. Профильные scalar/baseline/AVX2 времена нельзя трактовать как чистый SIMD speedup; выводы агрегированы по всем трём профилям. - Для N выше 1M выполнен один repeat на профиль, чтобы vector при N=100M оставался практически измеримым. - Исследован `uint32_t`; большие и non-trivial типы требуют отдельного large run. - v1 steady schedule был периодическим. Для основных N=100M-выводов выше используется исправленный seed-jittered v2. - Сохранённый бинарник использовал multiset-like финальный checksum: он ловил расхождение значений, но не гарантировал обнаружение перестановки. После run checksum заменён order-sensitive rolling digest; operation timer не изменён. - Сильные коэффициенты являются end-to-end regret короткой фазы, а не стационарной скоростью adaptive после уже завершённого перехода. Машиночитаемые данные: `large-raw.csv`, `cell-medians-large.csv`, `comparison-large.csv`, `comparison-by-size.csv`, `comparison-by-workload.csv`, `fixed-leaf-winners.csv`, `large-plan.json`, `environment.json`, source/binary manifests и per-cell partial/log файлы. Команды postprocess записаны в `analysis-command.txt`. Для повторения только этого N=100M holdout используется `large_benchmark.bat full 12 3 huge`; детали есть в `docs/benchmarking.md`.