604cffb5e5
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).
65 lines
2.1 KiB
Bash
Executable File
65 lines
2.1 KiB
Bash
Executable File
#!/bin/bash
|
||
# Phase 0 spike benchmark script. Запускать **внутри** dev-контейнера.
|
||
#
|
||
# Usage: ./tools/spike/bench.sh [SCENARIO]
|
||
# Scenarios: basic | multi-consumer | cross-container | stress
|
||
|
||
set -euo pipefail
|
||
|
||
cd "$(dirname "$0")/../.." # → корень репо
|
||
|
||
if [ ! -x build/pingpong_producer ]; then
|
||
echo "==> build first (cmake -B build -S tools/spike -G Ninja && cmake --build build)"
|
||
exit 1
|
||
fi
|
||
|
||
SCENARIO="${1:-basic}"
|
||
|
||
case "$SCENARIO" in
|
||
basic)
|
||
echo "=== Scenario: basic (1 producer × 1 consumer, FullHD@30fps, 1000 frames) ==="
|
||
./build/pingpong_producer --key cam_test --fps 30 &
|
||
PROD_PID=$!
|
||
sleep 1
|
||
./build/pingpong_consumer --key cam_test --count 1000
|
||
kill $PROD_PID 2>/dev/null || true
|
||
wait $PROD_PID 2>/dev/null || true
|
||
;;
|
||
|
||
multi-consumer)
|
||
echo "=== Scenario: 1 producer × 3 consumers ==="
|
||
./build/pingpong_producer --key cam_test --fps 30 &
|
||
PROD_PID=$!
|
||
sleep 1
|
||
./build/pingpong_consumer --key cam_test --count 500 > /tmp/c1.log 2>&1 &
|
||
./build/pingpong_consumer --key cam_test --count 500 > /tmp/c2.log 2>&1 &
|
||
./build/pingpong_consumer --key cam_test --count 500
|
||
wait
|
||
kill $PROD_PID 2>/dev/null || true
|
||
echo "--- consumer 1 summary ---"; tail -20 /tmp/c1.log
|
||
echo "--- consumer 2 summary ---"; tail -20 /tmp/c2.log
|
||
;;
|
||
|
||
stress)
|
||
echo "=== Scenario: 1-hour stress (FullHD@30fps, single consumer) ==="
|
||
./build/pingpong_producer --key cam_test --fps 30 --duration 3600 &
|
||
PROD_PID=$!
|
||
sleep 1
|
||
# Read forever (consumer завершится когда producer перестанет писать)
|
||
./build/pingpong_consumer --key cam_test --count 108000 -v
|
||
wait $PROD_PID 2>/dev/null || true
|
||
;;
|
||
|
||
cross-container)
|
||
echo "=== Scenario: cross-container ==="
|
||
echo "TODO: запустить второй контейнер с ipc:container:cuframes-dev"
|
||
echo " это в Phase 0 manual — задокументировать процесс в docs/"
|
||
;;
|
||
|
||
*)
|
||
echo "Unknown scenario: $SCENARIO"
|
||
echo "Available: basic | multi-consumer | stress | cross-container"
|
||
exit 1
|
||
;;
|
||
esac
|