OPTIM IDEAS 3 research
Источник:
dev/fera/project-design/context/OPTIM-IDEAS-3-research.md(read-only; сгенерировано scripts/sync-docs.mjs) Крупный ресерч по тотальной оптимизации потребления (память + CPU + энергия) с акцентом на OQ-024.
Цели из обсуждения:
- First-class: минимальное потребление в целом.
- Специальный режим экономии энергии (ещё агрессивнее).
- WASI-бэкенд как часть стратегии (менее агрессивный JIT / контролируемый overhead).
- Плагины через EBR (или гибрид).
- Форк modular runtime lib → сначала оптимизация, потом переписывание под ваш подход.
- Очень много DLL/libs* → оптимизация модели хранения в памяти + оптимизированная EBR-таблица под сотни модулей.
- Гибрид HP (большие/главные) + QSBR/EBR (мелкие).
- Акторная модель (ractor на Tokio) + эффективный work-stealing даже в 1–2 потоках.
- Thread parking + freeze фонового + выгрузка почти всех потоков (кроме управляющего + network) в idle/background.
Ниже — проверенные методы, trade-offs из исследований и конкретные идеи реализации.
1. Safe Memory Reclamation (EBR / QSBR / Hazard Pointers)
Section titled “1. Safe Memory Reclamation (EBR / QSBR / Hazard Pointers)”Классическое сравнение (Hart et al., IPDPS 2006 и последующие работы):
- QSBR — самый дешёвый на read-heavy (нулевые atomic’ы на hot path читателя). Идеален, когда quiescent points известны (акторные точки покоя, конец effect’а, idle в Tokio).
- EBR — почти так же дёшево (2 fences на операцию), но grace period может быть непредсказуемым при зависшем треде → unbounded memory.
- Hazard Pointers — предсказуемый bound памяти, но запись в hazard-slot на каждый доступ → memory traffic и хуже scalability на длинных traversals.
- Гибриды (QSense, EpochPOP, PEBR, Hazard Eras, DEBRA+, Crystalline и т.д.) дают лучшее из двух миров: fast-path EBR/QSBR + fallback HP при prolonged delays.
Ваш план (HP для главных больших модулей + QSBR/EBR для сотен мелких) — правильный.
Рекомендации под сотни модулей:
- Оптимизированная EBR-таблица: не глобальный epoch + limbo-листы на тред, а sharded / hierarchical структура (по группам модулей или по «горячим» vs «холодным»). Можно использовать token-passing / amortized free (Token-EBR + amortized freeing даёт 1.5–2× лучше throughput).
- Для hot-path вызовов таблиц указателей (каждый method call) — QSBR/EBR с guard на входе в эпоху (почти zero-cost для читателей).
- HP только на точках загрузки/выгрузки крупных модулей и на критических указателях, которые могут жить долго.
- Добавить quiescent points явно в акторную модель (конец обработки Effect’а, после await, в idle-паркинге Tokio). Это делает QSBR почти идеальным.
- Для предсказуемости в energy-mode: принудительный grace-period timeout + fallback на HP, если тред «спит» слишком долго.
Реализации в Rust: crossbeam-epoch, hazard-pointer crates, или свой лёгкий слой поверх (форк + переписывание internals).
2. Модель хранения сотен DLL / libs в памяти + Plugin System
Section titled “2. Модель хранения сотен DLL / libs в памяти + Plugin System”Проблемы при большом количестве модулей:
- Каждый
.so/DLL занимает адресное пространство + pages (даже если code pages shared). - Relocations, PLT/GOT, metadata.
- Hot-reload / unload без утечек.
Методы оптимизации (из исследований debloating, piecewise loading, shared-library awareness):
- Lazy / demand paging + selective loading. OS и так загружает pages on-fault. Можно дополнительно:
- Переупорядочить functions в .so (profile-driven) так, чтобы горячий код был компактным → меньше page faults.
- Piecewise / Nibbler-style debloating: статически или динамически вырезать неиспользуемые функции (до 50–80 % reduction code size в реальных lib).
- Shared code pages. Собирайте plugins с
-fPIC+ правильный rebase. Code pages разделяются между процессами (если несколько инстансов) и внутри процесса. - Единый runtime + thin plugins. Форкните modular runtime lib:
- Сначала агрессивно оптимизируйте (LTO, strip, feature flags, custom allocator).
- Перепишите internals под ваш storage model: вместо «каждый plugin = отдельный mapping» → единый arena / slab для metadata + code, или memory-mapped region с собственным loader’ом.
- EBR-таблица хранит только «handles» + epoch, а сами bodies живут в compact structure.
- WASI / Wasm Component Model как второй бэкенд (уже в планах).
- Преимущества для energy/low-memory: линейная память, fuel metering, capability security, очень быстрый cold-start (мс), контролируемый footprint (1–5 MiB на инстанс).
- Менее агрессивный JIT (или AOT + Winch baseline) → предсказуемее потребление.
- Плагины компилируются в Wasm, линкуются через EBR-обёртку (host-side table).
- Trade-off: небольшой overhead vs native, но для мелких модулей и energy-mode — выигрыш.
- Гибрид native + WASI. Главные/горячие модули — native (через оптимизированный EBR), остальные — Wasm. Или runtime-switch в energy-mode.
- Unload / freeze: при переходе в background/idle выгружайте cold plugins (munmap или Wasm instance drop), оставляя только network + control. EBR/QSBR гарантирует safety.
Библиотеки/подходы: libloading + свой safe wrapper, relib (reloadable), Wasmtime / WasmEdge (AOT, fuel, resource limits), Component Model для type-safe composition.
3. Tokio + Actor Model + Work-Stealing + Low Thread Count
Section titled “3. Tokio + Actor Model + Work-Stealing + Low Thread Count”Ваша цель «отлично работает в 1–2 потоках и максимально эффективно использует work-stealing» — полностью достижима.
Ключевые техники:
- Конфигурируемый размер worker pool (1 = phone/energy, N = desktop). ChatSupervisor / pool ChatActors — размер из конфига.
spawn_blockingтолько для реально блокирующего (Sanakirja disk IO, медиа-декодеры). Не ломает акторную модель.- Короткие Effects → Tokio любит это (LIFO slot + coop budget).
- Aggressive parking:
- В idle/background: выгрузить все worker’ы кроме control + network.
- Tokio уже имеет хороший park/unpark (condvar + driver). Можно дополнительно
thread::park+ явный freeze состояния акторов (сериализация/компрессия hot state). - Unparking mode (unstable в новых Tokio): cautious vs traditional — меньше spurious wakes.
- Work-stealing эффективность: держать задачи мелкими, избегать длинных critical sections, использовать local queues правильно.
- Current-thread runtime для extreme low-power режимов (нулевые cross-thread costs).
Дополнительно: CPU affinity (core_affinity crate), мониторинг runtime metrics, max_io_events_per_tick / event_interval tuning.
4. Специальный режим экономии энергии + Background Freeze
Section titled “4. Специальный режим экономии энергии + Background Freeze”Это должно быть first-class mode, а не «чуть поменьше потоков».
Конкретные идеи:
- Detect idle/background (OS signals, visibility, user inactivity, power status).
- Действия:
- Park / unload всех worker threads кроме 1 control + 1 network.
- Freeze / serialize / compress actor state (особенно ChatActors, кэши).
- Drop cold plugins (EBR grace period → unload).
- Сжать / выгрузить кэши (LRU → aggressive, или zstd in-memory).
- Перейти на current_thread runtime или минимальный multi-thread.
- Снизить timer resolution, отключить ненужные drivers.
- Fuel limits / throttling для Wasm-плагинов.
- Power-aware scheduling (меньше steal attempts, более агрессивный park timeout).
- При возврате: быстрый restore из frozen state + re-load нужных plugins по demand.
Аналогии: Android Doze / App Standby, iOS background modes, но на уровне вашего runtime.
5. Общие агрессивные оптимизации проекта
Section titled “5. Общие агрессивные оптимизации проекта”- Binary / memory footprint:
- LTO + strip + panic=abort + opt-level=z / s.
- Минимальные feature flags Tokio / зависимостей.
- Custom global allocator (mimalloc / jemalloc с тюнингом arena’ов, или свой slab для plugins).
- Zero-copy везде, где возможно (bytes crate, arena allocation).
- Debloating shared libs (Nibbler / piecewise / Negativa-style).
- Profile-guided optimization (PGO) + BOLT / Propeller для layout.
- Memory metrics + continuous profiling (особенно в energy-mode).
6. Предлагаемый roadmap для OQ-024
Section titled “6. Предлагаемый roadmap для OQ-024”-
Дизайн-проход:
- Финализировать гибрид HP/QSBR (где именно HP, где QSBR, quiescent points в акторах).
- Модель хранения libs: единый arena + EBR-handles vs отдельные mappings.
- WASI vs native split.
-
Форк runtime lib:
- Benchmark baseline.
- Оптимизации (LTO, allocator, debloat).
- Переписывание internals под EBR-таблицу + storage model.
-
Energy mode prototype:
- Thread parking + freeze + unload plugins.
- Configurable pool sizes.
- Metrics (RSS, CPU, wakeups).
-
Интеграция:
- Плагины через EBR-обёртку.
- Actor pool configurability.
- WASI backend как opt-in / energy-path.
-
Профилирование и итерации:
- Сотни модулей под нагрузкой.
- Idle → active transitions.
- Memory bound vs throughput.
Trade-offs и риски
Section titled “Trade-offs и риски”- QSBR/EBR: grace period может «зависнуть» → нужен timeout + HP fallback.
- Много native DLL: address space pressure (особенно 32-bit, но и на 64-bit при сотнях).
- Wasm overhead: приемлем для мелких, но горячий путь лучше native.
- Слишком агрессивный freeze: latency при «пробуждении».
- Сложность гибрида: профайлинг обязателен.
Это покрывает основные направления из исследований 2006–2026 годов (классика Hart/Michael + современные гибриды, debloating, Wasm Component, Tokio scheduler improvements). Можно углублять любой блок (конкретные crate’ы, псевдокод EBR-таблицы, design doc energy-mode и т.д.).