Skip to content

플랫폼 평가 — MCU 성능 및 서버 동시성

Xylolabs API — MCU 성능 평가 및 서버 동시성 분석 개정: 2026-03-29


1. 개요

본 문서는 Xylolabs 오디오 파이프라인을 실행하는 MCU 타겟의 실현 가능성을 평가하고, 서버 측 동시 스트림 수용량을 분석한다. MCU 측 측정은 Apple M 시리즈 호스트에서 --release 모드로 수행된 벤치마크를 기반으로 하며, DSP/FPU 가속 효과는 각 코어 아키텍처의 문서화된 MIPS 프로파일을 바탕으로 추정한다.


2. XAP 코덱 성능

2.1 프레임당 인코딩 시간 — 모노, 10ms (호스트 측정)

샘플레이트 Avg (us) 비고
8 kHz 0.6 코사인 테이블 사용
16 kHz 2.3 코사인 테이블 사용
24 kHz 5.0 코사인 테이블 사용
32 kHz 9.4 코사인 테이블 사용 (최대 N)
48 kHz 163.0 런타임 cosf() 폴백
96 kHz 630.9 런타임 cosf() 폴백

2.2 코사인 테이블 임계값

XAP_PRECOMPUTE_MAX_N = 320: N <= 320인 프레임(10ms 기준 최대 32kHz)은 O(N^2) 테이블 검색을 사용하며 런타임 삼각함수 호출이 없다. N > 320인 프레임(48kHz = 480샘플, 96kHz = 960샘플)은 MDCT 계수마다 런타임 cosf()를 호출한다.

48kHz에서 급격한 성능 저하가 발생하는 이유다. 32kHz (9.4 us) 대비 48kHz (163.0 us)는 약 17배 느리다.

실제 MCU 타겟에서 DSP 확장이 있는 경우, CMSIS-DSP의 arm_rfft_fast_f32가 이 전체 MDCT 경로를 대체하여 불연속이 제거된다. 호스트 벤치마크는 소프트웨어 전용 인코더 동작을 반영한다.


3. ADPCM 코덱 성능

3.1 프레임당 인코딩 시간 — 10ms

샘플레이트 채널 샘플 수 Avg (us) Min (us) Max (us) 예산 대비%
16000 1 160 0.93 0.83 7.21 0.009%
16000 2 320 1.83 1.71 2.58 0.018%
16000 4 640 3.70 3.50 10.21 0.037%
48000 1 480 2.87 2.62 9.58 0.029%
48000 2 960 5.68 5.38 12.33 0.057%
48000 4 1920 11.56 10.79 19.67 0.116%
96000 1 960 5.79 5.38 13.50 0.058%
96000 2 1920 11.51 10.83 20.42 0.115%
96000 4 3840 23.00 21.75 48.79 0.230%

ADPCM은 모든 구성에서 비용이 매우 낮다. 4ch@96kHz에서도 23 us (예산의 0.23%)만 소비한다. 스펙트럼 변환 없이 순수 정수 산술로 샘플별 델타를 룩업 테이블로 인코딩하기 때문이다.

3.2 XAP 대 ADPCM 비용 비율

구성 XAP (us) ADPCM (us) 비율
1ch@16kHz 2.3 0.93 2x
4ch@16kHz ~9.2 3.70 2x
4ch@48kHz ~652 11.56 ~56x
4ch@96kHz ~2524 23.00 ~110x

저 샘플레이트(32kHz 이하)에서는 코사인 테이블이 런타임 삼각함수를 제거하므로 XAP과 ADPCM의 비용이 근접한다. 48kHz 이상에서는 런타임 cosf()를 사용하는 O(N^2) MDCT로 인해 XAP이 수십 배 더 비싸진다. MCU 타겟에서 DSP 가속 FFT 경로는 이 격차를 크게 좁히지만 ADPCM은 CPU 제약 타겟에서 여전히 가장 가벼운 옵션이다.


4. DSP/FPU 가속 분석

DSP 아키텍처 플랫폼 주요 명령어 XAP 가속 비고
ARMv8-M DSP (Cortex-M33) RP2350, nRF9160 SMLAD dual MAC, QADD, SSAT ~30% 16비트 오디오에서 듀얼 MAC으로 처리량 2배. Q15 고정소수점 경로 선호.
Cortex-M4F FPU+DSP STM32F411, STM32WB55, nRF52840 FPU + SMLAD + SDIV ~35-40% 하드웨어 float 곱셈-누산 1-3 사이클. CMSIS-DSP arm_rfft_fast_f32로 MDCT 3-5배 가속.
Xtensa PIE SIMD (ESP32-S3) ESP32-S3 128비트 4x f32, 8x i16 ~60% 128비트 전용 레지스터에서 4-wide 벡터 연산. 하드웨어 AES/SHA가 TLS를 CPU에서 분리.
DSP 없음 RP2040, ESP32-C3, STM32F103 소프트웨어 곱셈 전용 없음 SIMD/하드웨어 float 없음. XAP MDCT는 소프트웨어 cosf() 필요 — DSP 가속 FFT 대비 10-50배 느림.

4.1 MDCT 경로 선택

MDCT forward transform은 인코더 핫 패스로, 전체 XAP 인코딩 시간의 60-70%를 차지한다. SDK는 컴파일 타임에 최적 경로를 선택한다.

코어 FPU 컴파일 경로 MDCT 전략
Cortex-M33 (RP2350, nRF9160) 단정밀도 cmsis-dsp feature Q15 고정소수점 + SMLAD dual MAC. Q15 형식 코사인 테이블 사전 계산.
Cortex-M4F (F411, WB55, nRF52840) 단정밀도 cmsis-dsp feature float + arm_rfft_fast_f32. 하드웨어 FPU에서 float 경로가 고정소수점보다 빠름.
Xtensa LX7 (ESP32-S3) 단정밀도 esp32-simd feature float + PIE 128비트 SIMD. 벡터 명령어당 f32 값 4개 처리.
Cortex-M0+ (RP2040) 없음 default (DSP 없음) 불가. 소프트웨어 float MDCT가 CPU 예산 초과. ADPCM 전용.
Cortex-M3 (STM32F103) 없음 default (DSP 없음) 불가. M0+와 동일. ADPCM 전용.
RISC-V (ESP32-C3) 없음 default (DSP 없음) 불가. M extension은 정수 곱셈만 제공, SIMD 없음. ADPCM 전용.

5. MCU 실현 가능성 매트릭스

5.1 타겟별 최대 지속 가능 구성

CPU%는 코덱 인코딩, I/O 스택(I2S DMA, 전송 프로토콜, 센서 샘플링), 시스템 오버헤드를 포함한다. RAM%는 SDK 클라이언트 상태, 코덱 버퍼, 링 버퍼, XMBP 프레이밍, 전송 스택, 태스크 스택을 포함한다.

타겟 클록 SRAM DSP 최대 구성 CPU% RAM% 판정
RP2350 150 MHz 520 KB M33 DSP+FPU 4ch@96kHz XAP 52.0% 16.9% 여유
ESP32-S3 240 MHz 512 KB PIE SIMD+FPU 4ch@96kHz XAP 37.1% 17.2% 여유
STM32F411 100 MHz 128 KB M4F DSP+FPU 4ch@96kHz XAP 71.0% 68.8% 빠듯
nRF52840 64 MHz 256 KB M4F DSP+FPU 4ch@48kHz XAP 67.2% 17.2% 가능
nRF9160 64 MHz 256 KB M33 DSP+FPU 4ch@48kHz XAP 73.4% 17.2% 빠듯
STM32WB55 64 MHz 256 KB M4F DSP+FPU 4ch@48kHz XAP 60.9% 19.5% 가능
STM32WBA55 100 MHz 128 KB M33 DSP+FPU 4ch@96kHz XAP 74.0% 39.1% 빠듯
RP2040 133 MHz 264 KB 없음 ADPCM 4ch@96kHz 3.0% 10.6% ADPCM 전용
ESP32-C3 160 MHz 400 KB M ext 전용 ADPCM 4ch@96kHz 2.5% 7.0% ADPCM 전용
STM32F103 72 MHz 20 KB 없음 ADPCM 2ch@24kHz 1.4% 60.0% 센서 전용

5.2 판정 기준

판정 CPU 사용률 의미
여유 < 50% 추가 처리, OTA 업데이트, 향후 기능 확장에 충분한 여유.
가능 50-70% 신중한 스케줄링으로 안정적 운영 가능.
빠듯 70-85% 운영 가능하나 최악의 인터럽트 지연 시 지터 발생 가능.
한계 85-100% 부하 시 프레임 드롭 위험. 프로덕션 비권장.
ADPCM 전용 해당 없음 DSP/FPU 없음. XAP 인코더 실행 불가. ADPCM 4:1 압축만 가능.
센서 전용 해당 없음 SRAM 극소. ADPCM 1-2ch + 센서 텔레메트리만 가능.

6. 타겟별 메모리 예산

6.1 타겟별 메모리 분석

단위: KB. 각 타겟의 최대 권장 구성 기준.

타겟 SRAM SDK+코덱 링 버퍼 XMBP HTTP 스택 사용 여유 RAM%
RP2350 520 20 32 16 4 16 88 432 16.9%
ESP32-S3 512 20 32 16 4 16 88 424 17.2%
STM32F411 128 20 32 16 4 16 88 40 68.8%
nRF52840 256 20 16 8 4 8 44 212 17.2%
nRF9160 256 20 16 8 4 8 44 212 17.2%
STM32WB55 256 20 16 2 0 12 50 206 19.5%
STM32WBA55 128 20 16 2 0 12 50 78 39.1%
RP2040 264 8 8 4 4 4 28 236 10.6%
ESP32-C3 400 8 8 4 4 4 28 372 7.0%
STM32F103 20 4 4 2 2 4 12 8 60.0%

STM32F411 (128 KB SRAM): 4ch@96kHz XAP = 88 KB (68.8%). 여유 40 KB는 OTA 스테이징 없이 애플리케이션만 수용 가능한 수준이다. 2ch@48kHz로 낮추면 사용량이 줄어 여유가 생긴다.

STM32F103 (20 KB SRAM): 센서 전용 ADPCM = 12 KB (60.0%). XAP은 불가 — 인코더 상태만으로도(채널당 8 KB, 4채널 32 KB) 전체 SRAM을 초과한다.

ESP32-S3: PSRAM 사용 시 오디오 링 버퍼와 XMBP 배치 버퍼를 PSRAM에 배치하여 빠른 SRAM을 코덱 상태와 스택에 확보할 수 있다. 4ch@96kHz 이상(예: 8ch@48kHz) 구성도 메모리 압박 없이 가능한 유일한 타겟이다.


7. 서버 동시성 분석

7.1 아키텍처 개요

Xylolabs API 서버는 Tokio 비동기 런타임과 Axum으로 구축된다. 인제스트 파이프라인(crates/xylolabs-server/src/routes/ingest.rs)은 MCU 디바이스의 XMBP 배치를 처리하고, 샘플을 메모리에 버퍼링하고, spawn_blocking에서 zstd로 압축하며, S3와 PostgreSQL에 플러시한다.

7.2 연결 파라미터

파라미터 비고
런타임 Tokio multi-threaded 워커 스레드 수 = CPU 코어 수
DB 커넥션 풀 20 (기본, 설정 가능) DATABASE_MAX_CONNECTIONS 환경 변수
세션당 메모리 ~1-4 KB (스트림 버퍼 제외) 누적 샘플 버퍼 별도
인제스트 플러시 윈도우 10초 (설정 가능) S3 쓰기 전 샘플 누적
세션 타임아웃 300초 (설정 가능) 비활성 세션 자동 종료
브로드캐스트 채널 용량 256 이벤트 초과 시 이벤트 폐기

7.3 락 계층

자원 락 타입 비고
IngestManager.sessions tokio::sync::RwLock 세션 등록/조회 시 읽기 락
개별 세션 tokio::sync::Mutex 플러시 중 I/O 전 락 해제
마지막 활동 시각 atomic u64 세션 뮤텍스 없이 갱신
ConfigManager tokio::sync::RwLock std::sync::RwLock에서 마이그레이션

7.4 동시 스트림 수용량

동시 스트림 수 안전성 비고
< 50 안전 경합 없음, 지연 50ms 이하
50-200 주의 DB 풀 50-100% 사용
200-1000 위험 풀 대기, 백프레셔 발생
> 1000 불안정 등록 실패, 메모리 급증

병목은 PostgreSQL 커넥션 풀(기본 20)이다. 플러시 작업마다 DB 커넥션이 필요하다. 100개 세션이 10초마다 플러시하면 커넥션당 ~10 flush/sec — 정상 범위. 200개 이상에서 플러시 윈도우가 겹치면 풀 고갈이 병목이 된다.

7.5 주요 병목

  1. DB 풀 (기본 20 커넥션): 동시 인제스트 플러시 + 트랜스코드 작업이 커넥션 소진. 200+ 세션에서 플러시 대기열 누적.
  2. 플러시 윈도우 차단: 여러 세션이 동시에 플러시할 때 DB 커넥션 경합. 개별 세션은 I/O 전 락을 해제하지만 커넥션 수가 한계.
  3. 브로드캐스트 채널 오버플로: 구독자 용량(256 이벤트) 초과 시 이벤트 무손실 폐기. 실시간 모니터링 클라이언트가 많을 때 발생.

8. 위험 요소 및 권장 사항

8.1 위험 요소

  1. 백프레셔 시 HTTP 500 반환 (429가 아님): 클라이언트가 과부하 상태와 서버 오류를 구분할 수 없어 재시도 폭풍이 발생할 수 있다.
  2. FFmpeg 프로세스 고아화: 트랜스코드 워커 패닉 시 자식 프로세스가 잔존한다. 프로세스 그룹 관리 없음.
  3. 메트릭/모니터링 부재: Prometheus 엔드포인트 없음. 커넥션 풀 포화 여부를 외부에서 감지할 수 없다.
  4. 트랜스코드 작업 고아화: 워커 크래시 시 작업이 "claimed" 상태로 최대 1시간 타임아웃까지 남는다.
  5. S3 대용량 파일 전체 RAM 버퍼링: 최대 256 MB 파일을 전체 메모리에 로드. 10개 동시 업로드 시 최대 2.56 GB RAM 소비.

8.2 권장 사항

우선순위 항목 설명
P1 DB 풀 확대 20 → 50+ (프로덕션). DATABASE_MAX_CONNECTIONS 환경 변수 및 PostgreSQL max_connections 동시 조정 필요.
P1 백프레셔 응답 코드 수정 HTTP 500 → 429. 클라이언트가 재시도 지연을 적용할 수 있도록.
P2 Prometheus 메트릭 엔드포인트 추가 DB 풀 사용률, 활성 세션 수, 플러시 지연 시간 노출.
P2 FFmpeg 프로세스 그룹 관리 워커 종료 시 자식 프로세스 정리. setpgid + SIGKILL 프로세스 그룹.
P3 트랜스코드 워커 하트비트 주기적 하트비트로 "claimed" 작업 고아화 조기 감지 및 재큐잉.

9. 관련 문서