76 lines
2.4 KiB
Markdown
76 lines
2.4 KiB
Markdown
|
|
---
|
|||
|
|
title: The measurements
|
|||
|
|
description: Every number on this site, with the methodology that produced it. Check our work.
|
|||
|
|
sidebar:
|
|||
|
|
order: 2
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
All numbers from **one** Raspberry Pi 4 + BerryGPS-IMU v4 (u-blox CAM-M8C), PPS on
|
|||
|
|
GPIO18. n = 1. Check them against your own board.
|
|||
|
|
|
|||
|
|
## Headline progression
|
|||
|
|
|
|||
|
|
| Change | RMS offset | Root dispersion |
|
|||
|
|
|---|---|---|
|
|||
|
|
| Baseline (stock kernel, stock chrony) | 823 ns | 16.8 µs |
|
|||
|
|
| chrony `filter 10` + `prefer` on PPS refclock | 440 ns | 5 µs |
|
|||
|
|
| PREEMPT_RT, unpatched | **2468 ns** ← *worse* | 11.6 µs |
|
|||
|
|
| **PREEMPT_RT + [`IRQF_NO_THREAD`](/reference/the-patch/)** | **199 ns** | 6.3 µs |
|
|||
|
|
|
|||
|
|
## Raw PPS jitter (kernel-timestamped)
|
|||
|
|
|
|||
|
|
| Kernel | jitter (σ) | peak-to-peak |
|
|||
|
|
|---|---|---|
|
|||
|
|
| Stock | 2134 ns | 11 µs |
|
|||
|
|
| PREEMPT_RT (threaded handler) | 6947 ns | 38 µs |
|
|||
|
|
| PREEMPT_RT + patch (hard-irq handler) | 2568 ns | 18 µs |
|
|||
|
|
|
|||
|
|
## The dashboard's tax
|
|||
|
|
|
|||
|
|
A/B/A, 62 s per round. [Why this matters](/explanation/the-observer-effect/).
|
|||
|
|
|
|||
|
|
| | Dashboard off | Dashboard on |
|
|||
|
|
|---|---|---|
|
|||
|
|
| Before fix | 1304 ns | 1912 / 2179 ns (**+36%**) |
|
|||
|
|
| After fix | 1437 ns | 1169 / 1450 ns (**no penalty**) |
|
|||
|
|
|
|||
|
|
## Things that did nothing
|
|||
|
|
|
|||
|
|
| Change | Result |
|
|||
|
|
|---|---|
|
|||
|
|
| Baud 9600 → 115200 | PPS offset **−1 ns** either way. Identical. |
|
|||
|
|
| SBAS disabled | No measurable change to PPS. |
|
|||
|
|
| `isolcpus` alone | Inconclusive-to-harmful (concentrates load onto the PPS core). |
|
|||
|
|
|
|||
|
|
## Methodology
|
|||
|
|
|
|||
|
|
**Don't trust chrony's own stats for this.** `chronyc sourcestats` reports a
|
|||
|
|
windowed, median-filtered figure that lags reality and hides what you're trying to
|
|||
|
|
see. Measure the kernel's PPS timestamps directly:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
sudo timeout 62 ppstest /dev/pps0 | awk '
|
|||
|
|
/assert/ {
|
|||
|
|
split($0, a, "assert "); split(a[2], b, ","); t = b[1] + 0;
|
|||
|
|
if (prev > 0) {
|
|||
|
|
d = (t - prev - 1.0) * 1e9; # deviation from exactly 1.000000000 s, in ns
|
|||
|
|
n++; sum += d; sumsq += d*d;
|
|||
|
|
if (d > max || n == 1) max = d;
|
|||
|
|
if (d < min || n == 1) min = d;
|
|||
|
|
}
|
|||
|
|
prev = t
|
|||
|
|
}
|
|||
|
|
END {
|
|||
|
|
mean = sum/n; sd = sqrt(sumsq/n - mean*mean);
|
|||
|
|
printf "n=%d jitter_sd=%.0f ns p2p=%.0f ns\n", n, sd, max-min
|
|||
|
|
}'
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Each pulse should be exactly 1.000000000 s after the last. The deviation *is* the
|
|||
|
|
jitter.
|
|||
|
|
|
|||
|
|
**Always run A/B/A**, never A/B. Clock behaviour drifts on the scale of minutes;
|
|||
|
|
if you measure on-then-off you cannot tell a real effect from thermal drift or a
|
|||
|
|
satellite geometry change. Go on → off → on, and require the two "on" rounds to
|
|||
|
|
agree before you believe the middle one.
|