148 lines
7.2 KiB
Markdown
148 lines
7.2 KiB
Markdown
# Universal Container
|
|
|
|
Экспериментальный C++20-контейнер индексируемой последовательности с двумя
|
|
представлениями. Текущая default-policy привязывает все автоматические
|
|
перестройки к изменению логической вместимости:
|
|
|
|
```text
|
|
capacity boundary
|
|
|-- grow: capacity *= 2 when the current capacity is exhausted
|
|
`-- shrink: capacity /= 2 at 12.5% occupancy
|
|
|
|
|
+-- small N: contiguous vector
|
|
`-- large N: tiered storage, leaf = ceil(sqrt(N))
|
|
```
|
|
|
|
Между изменениями вместимости контейнер не меняет ни представление, ни размер
|
|
leaf. На границе вместимости auto-mode заново выбирает `vector` или tiered,
|
|
поэтому обратный переход `tiered -> vector` также возможен. Focused cutoff
|
|
равен 4096 элементов; он выбран по baseline focused-run 7 x 100000 для
|
|
текущего `uint32_t` workload и остаётся калибруемой, а не универсальной
|
|
константой.
|
|
|
|
Поиск по значению не удалён: `AdaptiveSequence<T, true>` использует flat hash.
|
|
Число hash buckets рассчитывается из логической вместимости с запасом под
|
|
worst-case load не выше 70% и пересматривается только на той же границе
|
|
вместимости. Это исключает независимый rehash посреди обычной серии операций.
|
|
|
|
Старые многомерные benchmark-матрицы и сделанные по ним выводы сохранены только
|
|
как **historical / retired**. Активная постановка и ограничения описаны в
|
|
[docs/benchmarking.md](docs/benchmarking.md) и
|
|
[docs/findings.md](docs/findings.md).
|
|
|
|
## Быстрый старт
|
|
|
|
Из обычной командной строки Windows:
|
|
|
|
```bat
|
|
build.bat baseline test
|
|
```
|
|
|
|
Доступные профили:
|
|
|
|
```bat
|
|
build.bat scalar test
|
|
build.bat baseline test
|
|
build.bat avx2 test
|
|
build.bat all test
|
|
```
|
|
|
|
Проект проверен с Visual Studio 18 2026 и workload «Desktop development with
|
|
C++». `build.bat` сам находит комплектный CMake из Visual Studio. Готовые
|
|
программы находятся в
|
|
`out\bin\<profile>\Release\`:
|
|
|
|
- `uc_demo.exe` — минимальный пример;
|
|
- `uc_tests.exe` — differential/property-тесты;
|
|
- `uc_focused_bench.exe` — текущий focused benchmark runner;
|
|
- `uc_bench.exe` — historical / retired matrix runner.
|
|
|
|
Все Release-цели собираются с `/O2` и статическим MSVC runtime (`/MT`). Профиль
|
|
`scalar` — проверенный для MSVC 19.51 режим `project-novec`: внутренний ключ
|
|
`/d2Qvec-`, `/Oi-` и отключение vector algorithms STL. Это не универсальная
|
|
гарантия отсутствия SIMD внутри ABI/CRT. `baseline` оставляет штатную
|
|
автовекторизацию без AVX-флага, `avx2` добавляет `/arch:AVX2`. Перед запуском
|
|
AVX2-тестов и benchmark выполняется проверка CPU/OS; неподдерживаемый профиль
|
|
безопасно пропускается. Подробности приведены в
|
|
[docs/benchmarking.md](docs/benchmarking.md).
|
|
|
|
Текущий воспроизводимый запуск:
|
|
|
|
```bat
|
|
benchmark.bat
|
|
```
|
|
|
|
Он собирает и тестирует только профиль `baseline`, создаёт timestamp-папку и
|
|
один раз запускает `uc_focused_bench` с 100000 операций и 7 повторами. В
|
|
benchmark сравниваются три варианта одного типа
|
|
`AdaptiveSequence<uint32_t, true>`: forced vector, forced tiered и auto-mode;
|
|
flat hash включён у всех трёх. Mixed trace содержит 97% индексных чтений, 1%
|
|
hash-поисков `find_one` (50% hit / 50% miss), 1% вставок и 1% удалений. Runner
|
|
также печатает медианную пропускную способность каждого типа операций отдельно.
|
|
|
|
Raw CSV, metadata и медианная таблица `summary.md` сохраняются в
|
|
`results\benchmarks\<timestamp>-focused\`. Подтверждённая таблица публикуется
|
|
вместе с результатами запуска, а не вшивается в документацию до завершения
|
|
серии.
|
|
|
|
Следующие команды относятся к **historical / retired benchmark matrix** и не
|
|
являются текущим способом калибровки:
|
|
|
|
```bat
|
|
large_benchmark.bat smoke 12
|
|
large_benchmark.bat full 12 3
|
|
large_benchmark.bat full 12 3 huge
|
|
```
|
|
|
|
Старые CSV оставлены для аудита истории, но напрямую не сравнимы с focused
|
|
постановкой: в ней другой workload и hash обязателен у каждого кандидата.
|
|
`out\` полностью игнорируется Git, результаты исследования — намеренно нет.
|
|
|
|
## API
|
|
|
|
```cpp
|
|
#include <universal_container/adaptive_sequence.hpp>
|
|
|
|
uc::AdaptiveSequence<std::uint32_t> values;
|
|
values.push_back(10);
|
|
values.insert(0, 5);
|
|
values.erase(1);
|
|
auto x = values[0];
|
|
|
|
values.force_vector_mode();
|
|
values.force_tiered_mode({256, 64, 4});
|
|
values.enable_auto_mode();
|
|
values.adapt_now(); // default-policy не меняет mode между resize
|
|
```
|
|
|
|
Опциональный flat hash index со stable IDs:
|
|
|
|
```cpp
|
|
uc::AdaptiveSequence<std::uint32_t, true> indexed;
|
|
indexed.push_back(5);
|
|
indexed.push_back(5);
|
|
auto ids = indexed.find_all_ids(5);
|
|
indexed.erase_by_id(ids.front());
|
|
```
|
|
|
|
При включённом индексе запись через `operator[]` идёт через proxy и обновляет
|
|
индекс. Сам индекс не хранит логические позиции как ключи дубликатов.
|
|
|
|
## Каталоги
|
|
|
|
```text
|
|
include/universal_container/ публичные header-only компоненты
|
|
src/ demo и benchmark runner
|
|
tests/ correctness/differential tests
|
|
tools/ анализ CSV, аудит флагов, AVX2 probe и metadata
|
|
docs/ архитектура и выводы
|
|
results/benchmarks/ сохранённые результаты
|
|
out/build/ промежуточная сборка (ignored)
|
|
out/bin/ exe по профилям (ignored)
|
|
out/lib/ библиотеки (ignored)
|
|
out/symbols/ PDB по профилям (ignored)
|
|
```
|
|
|
|
Архитектура и контракт инвалидирования описаны в
|
|
[docs/architecture.md](docs/architecture.md).
|