docs(perception): record exact parity and fixed-envelope IPC comparison

This commit is contained in:
DCCONSTRUCTIONS
2026-09-02 14:28:58 +03:00
parent f39f1ff0b6
commit b8ba0cae1e
3 changed files with 182 additions and 6 deletions
@@ -1718,3 +1718,136 @@ operating envelope; затем production controller/admission/recovery/inventor
network ingress/egress и самостоятельный image. Старые product LAB/registry/UI
не переключены. Несколько/полная запись, physical source, field quality и
actuation не проверены. Этапы 3–4 не начаты; real-time qualification=false.
## 2026-09-02 14:22 МСК — этап 2, инкремент 6: exact pose и IPC без лишних copies
Коммиты: `380b6ea` (numeric layout), `f39f1ff` (IPC). Эксперимент
`perception-stage2-ipc-worker-20260902T1410MSK`. Итог: прежние два float-различия
устранены с exact parity полного графа 128/128 на двух повторах. Локальный
125-ms timing gate пройден в фиксированном штатном operating envelope; общий
real-time/network/physical-live статус по-прежнему не выдан.
### Причина численного расхождения и исправление
CPU-only bounded probe использует прежний producer для получения текущих
points/pose и неизменную KB4 projection. Никаких моделей или готовых perception
слоёв в новый граф не подмешивается: frozen observations нужны только для выбора
тех исходных point IDs, по которым сравнивается median range в диагностике.
32-camera prefix, без decode, source copy или полного source pass; этот
offline numerical probe не измеряет real-time latency.
В Worker NumPy 1.26.4 одинаковые quaternion bytes по адресу 8 mod 16 дают другое
округление `np.linalg.norm`, чем по адресу 0 mod 16. Новый combined pose wire body
содержит position (24 bytes) + quaternion (32 bytes), поэтому view quaternion начинался
на byte 24. Это не изменение source pose, association или расстояния как величины.
Управляемые offsets 8/24/40/56 mod 64 **точно воспроизводят** прежние два отклонения;
offsets 0/16/32/48, отдельные bytes и owning NumPy copy возвращают reference.
- seq13: norm `0x1.000033dcb5b18p+0` против reference `0x1.000033dcb5b19p+0`;
- seq29: norm `0x1.000035ea6dab2p+0` против reference `0x1.000035ea6dab3p+0`.
Норма влияет на rotation, projected depths и два опубликованных `range_m`.
Projected source indices остаются одинаковыми. Теперь sensor adapter создаёт
отдельную immutable 32-byte quaternion copy и проверяет 16-byte alignment;
эти bytes входят в существующий cache scratch allowance. Исходные значения,
norm/projection formula, distance-estimator definition и comparator не менялись.
Нового rounding/tolerance нет. Это восстановление numeric layout текущего
квалифицируемого runtime, не гарантия побитного равенства любого CPU/NumPy.
### Уменьшение копирования и CPU canary
Убраны `image.tobytes()` при передаче из decoder child и при отправке в DDRNet;
sender больше не делает `header + payload` с полной копией тела. Передаются
contiguous memoryviews, framing и body записываются отдельно. Partial writes
обрабатываются циклом; нулевой/неверный progress и noncontiguous input отвергаются.
Синхронный sender заимствует buffer только до завершения записи, поэтому прежний
owner не освобождает изображение раньше времени. Wire bytes, lease/epoch guards,
deadlines, queue/TTL budgets и модели не меняются.
Структурно удалены четыре копии BGR по 1,440,000 bytes на кадр на двух границах
decoder→parent→DDRNet. Это не zero-copy OS/kernel и не экономия сетевого трафика;
receiver buffers, model preprocess и обязательные transforms остаются.
CPU baseline/candidate выполняются отдельно, 128 исходных кадров при 1×,
2 CPU / 768 MiB, network none, без GPU request. У обоих BGR и sensor bundles
128/128 exact, residual input=0. Median RPC-minus-decode 1.621→1.060 ms,
p95 2.024→1.499 ms. При этом candidate native decode имел outlier 44.277 ms:
total source-due→dequeue p99 **ухудшился** с 21.323 до 31.722 ms. Это сохранено;
component-copy improvement не выдаётся за стабильный total-latency выигрыш.
### Полный A–B–BA в одном operating envelope
Порядок задан до запуска: baseline → candidate → candidate-repeat → baseline-repeat.
Все четыре отдельно, один полный профиль, serial GPU inference DDRNet + RF-DETR.
По ранее данному разрешению временно заданы штатные `-lgc 2610,2610` и
`-lmc 10501,10501`; **фактически все telemetry samples** показывают 2610/10251 MHz.
Без разгона, power-limit/CPU/RAM quota changes. Исходные 8 CPU / 8 GiB,
read-only/network-none, source clock 1×, без `/source.mp4` и полного preload.
Image/profile/weights/preprocess те же, что в предыдущем binary pilot;
baseline/candidate code snapshots и их hashes сохранены отдельно.
| Run, 128 кадров каждый | p95, ms | p99, ms | Raw observations exact | Fresh при receipt |
| --- | ---: | ---: | ---: | ---: |
| A: baseline | 84.702 | 92.961 | 126/128 | 76/128 |
| B: candidate | 85.113 | 91.219 | 128/128 | 76/128 |
| B: candidate-repeat | 82.425 | 90.530 | 128/128 | 76/128 |
| A: baseline-repeat | 83.930 | 91.759 | 126/128 | 76/128 |
Каждый: released/completed 128/128, drops/source_failed/unaccounted 0,
384/384 ingress observations, peak pending 1 при общем limit 2,
peak accounted input 8,761,039 bytes <16 MiB, residual input/children/lease 0.
Candidate first result 580.2580.3 ms, warmup 7.1317.146 s, stop 4.061 s.
VRAM peak 2363 MiB, RAM 3342.270/3358.859 MiB; CPU throttled delta 0.
Максимальный source release lag кандидатов 5.27 ms; source clock не замедляется.
Оба baseline повторили ровно прежние seq13/29 float differences; оба candidate
полностью совпали с reference по BGR, segmentation SHA, proposals, observations/
geometry ranges, tracks, threats, range-estimator metadata, material,
sensor binding/lineage и raw TGS costmap SHA. Дополнительно проверены surface
state/availability/authority flags и TGS points/ground/occupied/rejected counts.
Effective TTL-based costmap/policy сравниваются по validity, не как timeless raw.
Медианная накладная часть decoder RPC-minus-decode:
baseline 1.6421.825 ms → candidate 1.1001.118 ms; DDRNet RPC-minus-component:
2.1092.217 ms → 1.5581.613 ms. Это небольшой согласованный IPC выигрыш.
Full p95 не улучшился однозначно в обоих повторах; full p99 чуть ниже. По двум
samples нельзя обещать статистически устойчивое глобальное ускорение.
Разницу с предыдущими auto-clock 161.974/191.806 ms нельзя приписать копиям:
в текущих одинаковых clock conditions **контроль тоже** проходит timing gate.
Новый candidate в auto-clock режиме в этой итерации не измерялся.
Source gaps не «исправлены» ускорением: available/fresh 76/128, остальные 52
явно unavailable/stale по прежнему sensor contract. Новых receipt-age expirations
поверх available pairs нет. Все output freshness/TTL gates сохраняются;
physical-live, несколько/полная запись, качество и motor authority не допущены.
### Отказы, восстановление, evidence и следующий шаг
Candidate synthetic hung decoder повторно проверен CPU-only: timeout 250 ms,
terminal failed, source cameras 0/1/2 учтены как failed, child/lease/input
освобождены, остаток 0. 279 focused tests PASS; Ruff check/format 8 files,
Python 3.9 IPC lint и mypy common sensor module PASS. На Mac нет моделей,
нагрузочного/full-suite теста, Docker/image build или второго web service.
После A–B–B–A частоты сброшены в auto до восстановления сервисов. Triton
восстановлен первым, ready 200; остальные три Mission Core сервиса running.
Ollama/Frigate exited/restart=no. Временный experiment lease volume удалён после
сохранения released owner generation 4; recordings/models и старые artifacts
не тронуты. Все временные containers остановлены/удалены; Mac 8000=200,
8765 closed. Финальный GPU P8: 988 MiB, 210/405 MHz, power limit 450 W.
Manifest `.runtime/perception-stage2-ipc-worker-20260902T1410MSK/manifest.json`:
305 artifacts, SHA-256
`9c72a93833a1dda51c4787dca13fb9791a1bf2e31c763b7740e1b21406703707`.
Проверены hashes 228 code files на Worker; текущий код совпадает с измеренным
candidate. Сохранены CPU diagnosis/oracles/negative, четыре полных результата,
покадровые timings/parity, команды, before/quiesced/after, clock lock/reset,
terminal owner и final checks. Manifest связан с предыдущим binary evidence.
**Следующая работа этапа 2:** product controller/admission/recovery и continuous
operating-envelope/inventory, network boundary и standalone packaging.
Текущий bounded baseline позволяет идти дальше без изменения моделей и без
бесконечного ожидания идеального microbenchmark. Clock control не становится
автоматической властью будущего controller; installed/available/running/
qualified остаются разными состояниями. Старые LAB/registry/UI не переключены;
этапы 3–4 не начаты, global real-time qualification=false, actuation=false.