Files

115 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Контракт: производительность (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) на 816 ГБ (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 |