docs: 3-стадийный RX завершён — рабочая точка -p 3000 (§12.6)

Результаты свипа/соука 3-стадийного конвейера:
- FQ drops=0 на всех паузах (вкл. -p 0) — RS на ядре 1 не узкое место
- рабочая точка -p 6000 → -p 3000 (вдвое), соук 10 МБ чист (PER 0.26%)
- throughput 90 → 120 КБ/с = ×1.36 (исправлено с ошибочных ×4–5/×2:
  эфир кадра 5.33 мс доминирует над паузой)
- эмпирическое колено ~2500 против модели p_min 1333 (джиттер, запас 2×)
README §12.6; BENCHMARK p_min факт; test default
PAUSE=3000, TIMEOUT под 120 КБ/с. Исправлены ссылки §10 п.5→п.6 (ARQ
переехал при перенумерации). PHY не менялся.
This commit is contained in:
Maxim
2026-07-14 15:07:23 +03:00
parent 02cf711aec
commit 7b28ac8bd3
3 changed files with 61 additions and 22 deletions

View File

@@ -248,13 +248,14 @@ ssh root@192.168.2.1 '/tmp/ofdm_bench 1.92'
✅ 2026-07-14: первый OTA-приём — 10 КБ байт-в-байт, EVM 22.7 дБ (§12.3)
✅ 2026-07-14: пауза `-p 6000` убрала throughput-потери (100 КБ — 100/100);
на 1 МБ остаточный PER ≈ 0.2% (2 кадра). Побайтовый md5 на объёме отложен
на ARQ/дуплекс (п.5) — решение §12.3; веха симплекса = PHY-линия + PER
на ARQ/дуплекс (п.6) — решение §12.3; веха симплекса = PHY-линия + PER
4. ✅ 2026-07-14: антенны на столе — PER 10 МБ ≈ 0.36%, свип TX gain (§12.4),
рабочая точка 20 дБ; линия SNR-ограничена, целостность 100%
5. **3-стадийный RX-конвейер** (новый этап, вставлен по данным §12.5): ядро 0 —
только `ofdmflexframesync_execute`; ядро 1 — refill+конвертация **и RS-декод**
(снят с ядра синхронизатора). Цель: p_min ~1.3 мс вместо ~8 мс, throughput ×45.
`-p 0` на этом PHY недостижим (§12.5) — это осознанное ограничение, не цель.
5. ✅ 2026-07-14: **3-стадийный RX-конвейер** (§12.6): ядро 0 — только
`ofdmflexframesync_execute`; ядро 1 — refill+конвертация **и RS-декод**.
Рабочая пауза `-p 6000` → `-p 3000`, throughput 90 → 120 КБ/с (**×1.36**),
FQ drops 0 (RS не узкое место). `-p 0` на этом PHY недостижим — осознанное
ограничение; побайтовый лосслесс — через ARQ (п.6).
6. FDD 868/915 двусторонняя + ARQ с обратным каналом + меры из docs/NOTES.md
7. UDP-туннель поверх линка; затем web-настройка (libmicrohttpd)
8. Видео (raw UDP, пакеты ≤1472 Б) — при устойчивом PER
@@ -340,13 +341,13 @@ TX паузой `-p 6000` возвращает систематическую п
Дальнейшие рычаги: (1) **устойчивая передача файла** требует избыточности —
на симплексе это forward-redundancy (TX гонит файл N раз, RX пишет кадры по
`seq` в нужное смещение, дыры заполняются за проходы), полноценный ARQ — на этапе
дуплекса (§10 п.5); (2) двухпоточный конвейер RX (BENCHMARK §«резервы» п.2) —
дуплекса (§10 п.6); (2) двухпоточный конвейер RX (BENCHMARK §«резервы» п.2) —
поднимет throughput и позволит убрать паузу. `test_file_link.sh` теперь с
параметрами `PAUSE`/`FEC`/`TXGAIN`. **Рычаг (2) реализован и опровергнут —
см. §12.5.**
**Решение (2026-07-14):** побайтовый лосслесс на объёме отложен на этап дуплекса —
там ставится полноценный ARQ с обратным каналом (§10 п.5). На текущем симплекс-
там ставится полноценный ARQ с обратным каналом (§10 п.6). На текущем симплекс-
этапе forward-redundancy не внедряем; веха этапа — работоспособная PHY-линия и
измеренный PER.
@@ -375,7 +376,7 @@ TX паузой `-p 6000` возвращает систематическую п
**Итог симплекс-этапа:** PHY OTA-линия работает и охарактеризована по мощности,
целостность 100% (мусор в файл не попадает), PER ≈ 0.10.3% в рабочей зоне.
Остаток к «надёжной побайтовой» передаче = ARQ на этапе дуплекса (§10 п.5).
Остаток к «надёжной побайтовой» передаче = ARQ на этапе дуплекса (§10 п.6).
### 12.5 Двухпоточный RX и диагностика паузы (2026-07-14)
@@ -400,9 +401,43 @@ docs/BENCHMARK.md «Разбивка стоимости по стадиям»):
оставив RS (26%) на ядре синхронизатора.
**План:** 3-стадийный конвейер — ядро 0: только sync; ядро 1: refill+conv+**RS**
+запись. Модель p_min: ~3.4 мс (сейчас) → **~1.3 мс** → ~45× к throughput.
Абсолютный `-p 0` на этом PHY недостижим (нужен M=32/CP=8 или ARQ). Реализация
3-стадии — следующий шаг.
+запись. Модель p_min sync-only ~1.3 мс. Абсолютный `-p 0` на этом PHY недостижим
(нужен M=32/CP=8 или ARQ). Реализовано и измерено в §12.6.
### 12.6 3-стадийный RX-конвейер — результат (2026-07-14)
Реализован (receiver.c): поток A (ядро 1) refill+convert → кольцо сэмплов;
поток B (ядро 0) **только** `ofdmflexframesync_execute`, callback кладёт сырой
кадр в очередь fq; поток C (ядро 1) из fq → seq + RS + CRC-поверх-RS + запись.
Статистику печатает main. Два новых счётчика: `Overrun` (кольцо A→B) и
`FQ drops` (очередь B→C).
Свип паузы, 1 МБ, TXGAIN 20:
| `-p` | Кадров | Потери seq | Overrun | FQ drops | Оценка |
|---|---|---|---|---|---|
| 6000 | 1024 | 6 | 0 | 0 | чисто (SNR-пол) |
| 3000 | 1024 | 3 | 0 | 0 | **чисто — рабочая точка** |
| 2500 | 1024 | 0 | 0 | 0 | чисто (измеренный край) |
| 2000 | 1006 | 20 | 7 | 0 | колено (sync не успевает) |
| 1000 | 971 | 56 | 15 | 0 | перегруз sync ядра 0 |
| 0 | 970 | 52 | 15 | 0 | перегруз sync ядра 0 |
Соук 10 МБ на `-p 3000`: Потери 27/10240 = **PER 0.26%**, Overrun 0, FQ drops 0 —
чисто по throughput, остаток чисто SNR (как §12.4).
**Выводы:**
- **`FQ drops = 0` на всех паузах, включая `-p 0`** — поток C (RS на ядре 1) ни
разу не отстал. Тезис «RS на второе ядро» подтверждён: RS больше не узкое место.
- Единственный лимит — sync на ядре 0 (`Overrun`): чисто до `-p 2500`, колено
на `-p 2000`. Реальное колено ~2500 выше нуль-запасной модели p_min 1333 мкс
из-за джиттера/маржи планировщика (запас ~2×).
- **Рабочая точка: `-p 3000`** (вдвое меньше прежних `-p 6000`), соук-подтверждена,
запас ~1000 мкс до overrun. Throughput 1024 Б/(5.33+3 мс) ≈ **120 КБ/с** против
~90 КБ/с на `-p 6000` = **×1.36** (не ×45 — эфир кадра 5.33 мс доминирует над
паузой; прежняя оценка исправлена).
- `-p 0` по-прежнему недостижим (sync сам 0.86× realtime, §12.5) — осознанное
ограничение PHY, лосслесс на объёме — через ARQ (§10 п.6).
---
*Ввод в строй: 2026-07-14. Замеры CPU и базовые решения — 2026-07-10.

View File

@@ -125,17 +125,20 @@ sync-only **1.649 vs 1.652** без него = 0.2%. Гипотеза кэш-к
Условие на период кадра: `sync(кадр) + sync(шум в паузе) + RS ≤ эфир(кадр+пауза)`.
| Что на ядре 0 (поток B) | p_min | подтверждение |
| Что на ядре 0 (поток B) | p_min модель | факт (колено Overrun) |
|---|---|---|
| sync + RS + conv (однопоток, было) | ~56 мс | старая база §12.3: `-p 6000` чисто |
| sync + RS (текущий двухпоток) | ~3.4 мс | колено: `-p 4000` ещё Overrun, `-p 8000` чисто |
| **sync only (цель 3-стадии)** | **~1.33 мс** | вынос RS на ядро 1 |
| sync + RS + conv (однопоток, было) | ~56 мс | `-p 6000` чисто (§12.3/12.4) |
| sync + RS (двухпоток) | ~3.4 мс | `-p 4000` ещё Overrun, `-p 8000` чисто |
| **sync only (3-стадия, реализовано)** | ~1.33 мс | **`-p 2500` чисто, `-p 2000` колено 12.6)** |
**Вывод:** `-p 0` вне досягаемости этого PHY. Реальная цель 3-стадийный
конвейер (ядро 0: только sync; ядро 1: refill+conv+RS+запись), p_min
1.32 мс с запасом **~45× throughput** против нынешних 8 мс. Абсолютный
лосслесс на потоке требует либо дешевле PHY (M=32/CP=8, резерв п.1), либо ARQ
(этап дуплекса) вне текущего этапа.
**Итог (§12.6):** 3-стадийный конвейер реализован, RS вынесен на ядро 1
(`FQ drops = 0` на всех паузах RS не узкое место). Рабочая точка **`-p 3000`**
(вдвое меньше прежней), соук 10 МБ чист (Overrun 0, PER 0.26% SNR-пол).
Эмпирическое колено ~2500 мкс выше нуль-запасной модели 1333 из-за джиттера
планировщика (запас ~2×). Throughput 90 120 КБ/с = **×1.36** (не ×45:
эфир кадра 5.33 мс доминирует над паузой). Абсолютный `-p 0` недостижим
sync сам 0.86× realtime; лосслесс на объёме через ARQ или дешевле PHY
(M=32/CP=8, резерв п.1).
## Неисследованные резервы (если понадобится > 1.92 MSPS)

View File

@@ -16,8 +16,9 @@ RATE=1920000 # НЕ поднимать: бюджет CPU, docs/BE
BW=1500000
TXGAIN="${TXGAIN:--30}" # OTA: переопредели, напр. TXGAIN=-20 scripts/test_file_link.sh
FEC="${FEC:-rs8}" # rs8 | none — фаза 3.2 гоняет сначала none, потом rs8
PAUSE="${PAUSE:-6000}" # пауза TX между кадрами, мкс. -p 0 топит однопоточный RX (§12.3)
TIMEOUT=$(( SIZE_KB / 50 + 30 )) # ~80 КБ/с с паузой + запас (см. PAUSE)
PAUSE="${PAUSE:-3000}" # пауза TX между кадрами, мкс. Рабочая точка 3-стадийного
# RX (§12.6): чисто, ~120 КБ/с. Ниже ~2500 — Overrun на ядре 0
TIMEOUT=$(( SIZE_KB / 80 + 20 )) # ~120 КБ/с на -p 3000 + запас (см. §12.6)
if command -v sshpass >/dev/null; then
SSH=(sshpass -p "$PLUTO_PASS" ssh -o StrictHostKeyChecking=no)