# 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-.handle`) - Не делает proper backpressure (drop-oldest hardcoded) Spike нарочно **минималистичен** — единственная цель замерить numbers и провалидировать concept перед инвестированием в Phase 1.