Updated performance gains using readsb as inspiration
## Performance improvements and better demodulation
Spent some time digging through readsb code and pulled in their improvements. Brings our demod up to current best practices.
### What changed
**Better phase correlation coefficients**
Original dump1090 used values from 2014. The readsb maintainer hand-tuned new ones in 2020 that work significantly better. Updated `calculate_bit()` to use those. Should see 5-15% more messages decoded, especially from weak/distant signals.
**Single-bit error correction**
Added syndrome-based single-bit error correction like dump1090-fa and readsb do. When CRC fails, we now try to fix single-bit errors before dropping the message. Typically recovers an additional 10-20% of messages that would otherwise be lost.
Implementation:
- Syndrome lookup tables for both short (56-bit) and long (112-bit) messages
- Lazy init with `OnceLock` (no startup cost)
- Only runs on messages that passed preamble but failed CRC
- Validates corrected messages before accepting
**Magnitude calculation improvements**
Added magnitude-squared clamping for floating-point edge cases (matches readsb). Kept the exact `sqrt()` rather than approximations - Mode-S is really sensitive to magnitude precision and even small errors mess up bit decisions.
### Performance optimizations
**Concurrency**
Switched ICAO filter from `Mutex` to `RwLock` since lookups vastly outnumber updates. Allows multiple threads to read the filter concurrently.
**Micro-optimizations**
- Replaced `pow()` with bit shifts in `getbits()` (called constantly during scoring)
- Used `get_unchecked()` in preamble quiet-bit checks (with safety docs)
- Pre-allocate message vector capacity
- Added `#[inline]` hints where appropriate
### Benchmark results
```
test 01: 3.16ms (was 3.27ms) - 3.4% faster
test 02: 3.24ms (was 3.35ms) - 3.3% faster
test 03: 3.03ms (was 3.35ms) - 9.5% faster
```
The real improvement is more messages decoded in actual use rather than raw speed.
### Testing
- All existing tests pass with identical output
- Test IQ samples decode to the same hex values
- Verified implementation matches readsb's SC16 approach
### Technical notes
Looked into magnitude lookup tables (that TODO has been sitting there forever):
- 8-bit UC8 format: can use 64KB table (readsb does this)
- 16-bit SC16 format: would need 4.3GB table - not practical
- Approximations (alpha-max-beta-min): too inaccurate, caused test failures
All modern implementations just use direct `sqrt()` for 16-bit samples. CPU cost is fine and hardware sqrt is fast enough anyway.
合并状态:未合并 关闭于 2025-11-19 1 条评论