Files
cuframes/tools/spike/README.md
T
gx 604cffb5e5 spike(phase0): minimal CUDA IPC ping-pong producer/consumer
PoC для validation концепта перед инвестированием в Phase 1.

Структура:
- tools/spike/common.h          — типы SharedHeader / SlotDescriptor / NV12 meta
- tools/spike/pingpong_producer.cu — аллоцирует CUDA pool, экспортирует IPC handles
  в /dev/shm/cuframes-spike-<key>, имитирует publish frames с monotonic pattern
- tools/spike/pingpong_consumer.cu — открывает handles, читает frames,
  verify содержимого (no torn frames), измеряет latency, печатает summary
- tools/spike/CMakeLists.txt    — sm_75/86/89/90/120 для RTX 5090
- tools/spike/bench.sh          — basic / multi-consumer / stress scenarios
- tools/spike/README.md         — what / how / acceptance

Намеренные упрощения PoC (не идём в Phase 1 пока без validation):
- 2-slot ring (Phase 1 будет N)
- POSIX shared memory + atomic seq (без Unix socket handshake)
- cudaStreamSynchronize sync (Phase 0 spike проверит будет ли достаточно;
  альтернатива cudaIpcEventHandle_t — отложена)
- NV12 hardcoded (других форматов в Phase 1)
- Drop-oldest backpressure (без ACK protocol)

Acceptance Phase 0:
- p99 latency на RTX 5090 для FullHD < 5 ms
- throughput ≥ 1 GB/s
- multi-consumer (3) с сопоставимой latency
- cross-container работает
- 1-hour stress без VRAM/RAM leak

Если acceptance fail → дизайн пересмотр (sync через CUDA IPC events).
2026-05-14 21:20:39 +01:00

95 lines
3.7 KiB
Markdown
Raw 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.
# Phase 0 — CUDA IPC ping-pong spike
PoC для измерения latency / throughput / multi-consumer behavior **без**
FFmpeg / Frigate / сложности. Чистый CUDA IPC между двумя процессами.
## Что проверяет
1. **End-to-end latency**: producer → write CUDA frame → consumer reads → ACK.
2. **Throughput**: сколько FullHD-frames/sec можно протолкнуть.
3. **Multi-consumer**: 1 producer × N consumers (zero-copy для каждого).
4. **Cross-container**: producer и consumer в разных Docker-контейнерах.
5. **Crash recovery**: kill consumer / producer → reconnect.
6. **Memory leak**: 24-hour run без VRAM-роста.
## Структура
```
tools/spike/
├── README.md (этот файл)
├── CMakeLists.txt стандартный CMake target
├── common.h shared structs/constants
├── pingpong_producer.cu producer-процесс
├── pingpong_consumer.cu consumer-процесс
└── bench.sh скрипт-обвязка с измерениями
```
## Сборка (внутри dev-контейнера)
```bash
docker compose -f docker/docker-compose.dev.yml exec dev bash
# Внутри:
cd /workspace
cmake -B build -S tools/spike -G Ninja
cmake --build build
```
Артефакты: `build/pingpong_producer`, `build/pingpong_consumer`.
## Запуск (single-host single-container, базовый случай)
Терминал 1 (producer — пишет FullHD-frames пока не нажмёшь Ctrl-C):
```bash
docker compose -f docker/docker-compose.dev.yml exec dev \
./build/pingpong_producer --key cam_test --width 1920 --height 1080 --fps 30
```
Терминал 2 (consumer — читает и логирует latency):
```bash
docker compose -f docker/docker-compose.dev.yml exec dev \
./build/pingpong_consumer --key cam_test --count 1000
```
После 1000 кадров consumer печатает summary:
```
=== cuframes spike summary ===
frames received: 1000
duration: 33.34 s
fps: 30.00
latency mean: 0.42 ms
latency p50: 0.39 ms
latency p99: 0.91 ms
latency max: 3.12 ms
producer→consumer: zero-copy ✓
```
## Запуск (cross-container — Phase 0 critical test)
См. `bench.sh` — поднимает producer в одном контейнере, consumer в другом,
оба используют `ipc: shareable` namespace.
## Acceptance criteria для Phase 0
- [ ] Базовый ping-pong работает (1×1)
- [ ] Multi-consumer (3 consumers, latency сопоставимая)
- [ ] Cross-container (producer container A → consumer container B)
- [ ] 1-hour stress без VRAM/RAM leak
- [ ] Замерено: p99 latency на RTX 5090 для FullHD-frame
- [ ] Документ `docs/benchmarks-phase0.md` с numbers
Если latency p99 > 5 ms или throughput < 1 GB/s → **остановиться** и
переосмыслить дизайн (возможно CUDA IPC sync через `cudaIpcEventHandle_t`
вместо `cudaStreamSynchronize`).
## Что **не** делает spike
- Не использует FFmpeg (это Phase 2)
- Не имеет ring buffer (это Phase 1; spike использует двойной буфер)
- Не использует Unix sockets для handshake (handle передаётся через
файл `/tmp/cuframes-spike-<key>.handle`)
- Не делает proper backpressure (drop-oldest hardcoded)
Spike нарочно **минималистичен** — единственная цель замерить numbers
и провалидировать concept перед инвестированием в Phase 1.