diff --git a/docs/README.md b/docs/README.md index 89229db..f2e79e7 100644 --- a/docs/README.md +++ b/docs/README.md @@ -19,7 +19,7 @@ - [tech-stack.md](tech-stack.md) — канонический технический стек (Rust-first) и крейты. ### Tier 1 — сквозные контракты (соединительная ткань) -- [contracts/](contracts/README.md) — IPC, модель данных, plugin-SDK, безопасность/приватность, safety (граница+distraction), железо. +- [contracts/](contracts/README.md) — IPC, модель данных, plugin-SDK, безопасность/приватность, safety (граница+distraction), производительность (NFR), железо. ### Инфраструктура разработки - [dev-environment.md](dev-environment.md) — как вести разработку изолированно, с Mac. diff --git a/docs/contracts/README.md b/docs/contracts/README.md index 3be0af7..aba3a7d 100644 --- a/docs/contracts/README.md +++ b/docs/contracts/README.md @@ -12,6 +12,7 @@ | `plugin-sdk.md` | API расширения: манифест, capability-модель, точки расширения (экраны, тайлы, интенты, доступ к данным). *Рантайм плагинов — домен F.* | | `security-privacy.md` | Sandboxing плагинов, модель разрешений, обработка данных, 152-ФЗ. | | `safety.md` | Граница «не safety-critical» + структурный энфорсмент red-lines (CAN read-only) + driver-distraction-политика. *Комплемент security-privacy: вред/отказы, не злоумышленник.* | +| `performance.md` | NFR-бюджеты: латентность, кадровый бюджет, память/ресурсы, тепло — принцип #11 как измеримый контракт. | | `hardware.md` | Целевой таргет (RK3588), топология питания, периферия + **HAL/board-support API** для портирования на другое железо/авто. | > Важный нюанс: **plugin-SDK** (API, тут) и **домен F «Plugin host»** (рантайм, diff --git a/docs/contracts/performance.md b/docs/contracts/performance.md new file mode 100644 index 0000000..f5d6986 --- /dev/null +++ b/docs/contracts/performance.md @@ -0,0 +1,114 @@ +# Контракт: производительность (NFR-бюджеты) + +> Принцип #11 (отзывчивость) сделан **измеримым**: свод тестируемых бюджетов на +> латентность, память и ресурсы. Цель — поймать регрессии как **баги**, а не «потом». +> Прочие NFR — в своих доках: безопасность/distraction → [safety.md](safety.md), +> угрозы/приватность → [security-privacy.md](security-privacy.md). + +Статус: **v1 (черновик на ревью).** +Связано с: [principles.md](../principles.md) (#11) · [architecture.md](../architecture.md) (§6 boot) · домены [A](../domains/a-base-system.md) (§4/§8/§10), [D](../domains/d-assistant.md), [E](../domains/e-vehicle-data.md), [H](../domains/h-media-audio.md), [J](../domains/j-cameras-video.md), [F](../domains/f-plugin-host.md) · [data-model.md](data-model.md) (`max_age`) · [hardware.md](hardware.md) + +--- + +## 1. Назначение + +- Свести разрозненные перф-обещания корпуса в **единый набор бюджетов** + до-определить + недостающие латентные числа (как safety до-определил distraction). +- **Бюджет — это контракт:** цель измеряема, нарушение — регрессия-баг (#11), а не вкусовщина. +- **Скоуп:** латентность · кадровый бюджет · память/ресурсы · тепловая устойчивость. НЕ дублирует + safety/security/privacy. + +## 2. Таргет-тиры и где меряем + +- **Эталон измерения — реальное железо RK3588** (target-голова), **не** dev-Mac (он быстрее и + вводит в заблуждение). Dev-VM — для функционального теста, не для перф-вердикта. +- **Тиры RAM:** **min 8 ГБ** (впритык — деградация по a-base §8) / **target 16 ГБ** (комфорт). + Бюджеты ниже — для target-тира; на 8 ГБ допускается видимая деградация (не stall), порядок + жертв — §8. +- Числа-**🟡** — предлагаемые дефолты под подтверждение; финал — на реальном HMI/железе. + +## 3. Сводная таблица бюджетов + +✅ = зафиксировано в корпусе · 🟡 = предлагаемый дефолт. + +| Категория | Бюджет (цель) | Где / примечание | Статус | +|-----------|---------------|------------------|--------| +| **Boot** splash (Stage 0) | ≤ ~1 c от питания | architecture §6, A §4 | 🟡 | +| Первый интерактивный кадр | **ASAP; потолок < 10 c** | потолок, не цель (§4) | ✅ <10c (корпус: как цель) · 🟠 «потолок» — рамка дока | +| TTFF задней камеры (реверс→кадр) | ≤ ~1 c | ранний путь Stage 0 — J §3, hw §4 | 🟡 | +| **UI** кадр | **60 fps / ≤ 16.6 ms**, без jank | steady-state на target | 🟡 (из #11) | +| Отклик на ввод (тач/руль→реакция) | ≤ ~100 ms | C §9 (ввод) | 🟡 | +| **Аудио** wake-word детект | ≤ ~400 ms | D §2 пайплайн | 🟡 | +| ducking-реакция (фокус→приглушение) | ≤ ~150 ms | H §3 | 🟡 | +| старт TTS после решения | ≤ ~300 ms | D, H | 🟡 | +| **Ассистент** локальный интент (громче/домой) | ≤ ~300 ms, **без сети/LLM** | D §6 (латентно-крит.) | ✅ стойка · 🟡 число | +| голос end-to-end онлайн (wake→начало ответа) | цель ≤ ~2.5 c; **«думаю…»** если > ~1.5 c | D §2/§5, online-LLM, D11 | 🟡 | +| офлайн-фолбэк | деградация (латентность выше — ок), не отказ | D §5 (v3) | ✅ стойка | +| **Vehicle-data** rate-cap подписки | **~10–20 Гц** (агрегатный потолок шины) | ipc §3, E §5a | ✅ корпус | +| бюджет опроса req/s | per-transport (ELM327 half-duplex ≪ нативный CAN) | E §3 (бюджет/коалесцирование) | ✅ корпус | +| staleness сигнала | старше `max_age` (per-signal абсолютный порог) → `stale`; таймаут/транспорт → `unavailable` | data-model §2 (`max_age`/quality); E §7 (runtime, open); E §5b (транспорт) | 🟡 значения · ◻️ E §7 | +| **Память** тиры | **min 8 / target 16 ГБ** | hw §1, A §8 | ✅ корпус | +| per-service RAM | core малы; App-Host/тяжёлые — cgroup `MemoryMax/High` | A §8 | ✅ стойка · 🟡 числа | +| OOM-порядок жертв (первые) | **сторонний плагин** → офлайн-LLM → фон-апы → throttleable dashcam/surround | A §8, F §2a | ✅ корпус | +| бюджет плагина | cgroup + OOM-приоритет | F §2a | ✅ стойка · 🟡 числа | +| **Тепло** throttle-поведение | деградировать **видимо**, не stall | паттерн A §8 / J §9; throttling — A §10, конверт — hw §1a | ✅ корпус | + +## 4. Boot / старт *(потолок ≠ цель)* + +- **< 10 c до интерактива — это потолок-требование** (must-not-exceed), **не цель.** Цель — + **как можно быстрее**: splash мгновенно (Stage 0), первый кадр ASAP (#11). Быстрее всегда лучше. +- **Фазы** (architecture §6, A §4): Stage 0 (загрузчик→splash + низколатентный путь задней + камеры) → Stage 1 (ядро + UI critical set) → Stage 2 (остальное лениво). +- **Caveat verified-boot:** `< 10 c` меряется **без** проверки подписи. Secure boot (v4) + добавляет задержку Stage 0 (хэш многомегабайтного образа) — **мерить отдельно** (A §5, hw §4). +- **TTFF задней камеры** — отдельный жёсткий бюджет (реверс — почти прямой путь, architecture §6): + кадр должен появиться раньше, чем водитель начал маневр. + +## 5. Память и ресурсы + +- **Давление — видео-пайплайн** (DMABUF камер / VPU-кодирование dashcam) на 8–16 ГБ (A §8). +- **cgroup `MemoryMax/MemoryHigh`** на App-Host и тяжёлые апы; **zram** + OOM-настройка. +- **Порядок жертв OOM** (защищаем critical set + низколатентную заднюю камеру): сначала + **сторонний плагин** (F §2a — ниже офлайн-LLM) → **офлайн-LLM → фоновые апы → throttleable + dashcam/surround** (деградируют **видимо**, не stall). +- **8 ГБ — впритык, 16 ГБ — комфорт** (A §8). Per-service RAM-числа — 🟡 (профилировать на железе). + +## 6. Тепло и устойчивость + +- Бюджеты — **steady-state**, не burst: важна устойчивая работа под нагревом салона (worst-case + sun-load), а не пиковая цифра. +- **Throttling** (A §10) деградирует **видимо** (паттерн «видимо/не stall» — A §8 / J §9) и не заменяет тепловой конверт (hw §1a) — если + железо вне класса, софт не лечит. + +## 7. Методология и энфорсмент + +- **Где меряем:** E2E в VM (функционально) + **HW-in-the-loop на RK3588** (перф-вердикт) — + [dev-environment.md](../dev-environment.md). +- **CI perf-gate:** ключевые бюджеты (boot, кадр, отклик, голос) — автотест; **регрессия = баг**, + блокирует, не «потом» (#11). +- **Бюджеты — на target-тире**; dev-Mac-числа не засчитываются как вердикт. + +## 8. Зависимости / связи + +- **Принцип #11** — корень; этот док его операционализирует. +- **A** §4 (boot), §8 (память/OOM/cgroup), §10 (тепло). **architecture** §6 (boot-стадии). +- **D** (латентность ассистента), **H** (аудио-латентность/ducking), **E** §3 (бюджет опроса), §5a (потолок/safety), §5b/§7 (staleness), + **J** §3 (TTFF камеры), §9 (видимая thermal-деградация), **F** §2a (бюджет/OOM плагина), **data-model** §2 (`max_age`/quality), **hardware** §1/§1a (RAM/конверт), §4 (TTFF). +- **Комплементы:** [safety.md](safety.md) (distraction/red-lines), [security-privacy.md](security-privacy.md). + +## 9. Открытые вопросы + +- 🟡 **Латентные числа** (кадр/ввод/wake/голос/ducking/TTS) — финализировать на реальном HMI/железе. +- 🟡 **Per-service RAM-бюджеты + per-signal `max_age`** (runtime-staleness — E §7 open) — профилировать/согласовать на target. +- ◻️ **Деградация-матрица на 8 ГБ** — что именно и в каком порядке урезается (расширить §5). +- ◻️ **Состав CI perf-gate** (какие бюджеты автоматизируем первыми) — к v0-инфре. + +## Журнал решений (performance) + +| Решение | Выбор | Дата | +|---------|-------|------| +| Эталон измерения | реальное железо RK3588 (target-тир), не dev-Mac | 2026-06-23 | +| Boot-бюджет | в корпусе (architecture §6 / #11 / A §4) `< 10 c` = **цель**; здесь реклассифицируем в **потолок** (must-not-exceed), цель — ASAP | 2026-06-23 | +| Тиры RAM | min 8 ГБ (деградация) / target 16 ГБ (комфорт) | 2026-06-23 | +| Латентные дефолты | предложены (🟡): кадр ≤16.6 ms, ввод ≤100 ms, голос ≤2.5 c / «думаю…» >1.5 c | 2026-06-23 | +| Энфорсмент | CI perf-gate; регрессия = блокирующий баг (#11) | 2026-06-23 |