# Контракт: производительность (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 |