bus-bench: decoder stand-in and mixed-load runs
Raw frames to four subscribers plus envelopes to five, at the car's rate and at a full bus. Raw never suffered; envelope deliveries are the load, with the knee near 40,000 deliveries/s. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DDwfd6Ki8UfG4hK6W5YpJz
This commit is contained in:
@@ -12,6 +12,7 @@ The car's usual services (recorder, orin-status, svc-gw, svc-vision) kept runnin
|
||||
|
||||
```bash
|
||||
scripts/bus-bench.sh ./bus-bench z27ag-20261009-163736-ign.log 20 # on the Orin
|
||||
scripts/bus-mix.sh ./bus-bench z27ag-20261009-163736-ign.log 20 # after bus-bench.sh
|
||||
```
|
||||
|
||||
Loads:
|
||||
@@ -67,10 +68,56 @@ The car's broker now has `set_tcp_nodelay true` (orin-nano-env-setup `MOSQUITTO.
|
||||
Clients that publish or consume raw CAN set `set_tcp_nodelay(true)` too. At once a
|
||||
second (orin-status) it does not matter.
|
||||
|
||||
## The bus as the car will use it
|
||||
|
||||
`scripts/bus-mix.sh`: the raw stream (10 ms batches) to four subscribers (the decoder
|
||||
plus three: svc-gw, telemetry-gw, a debug tool), and a stand-in `decoder` publishing
|
||||
envelopes on one retained topic per signal, to five subscribers that each take every
|
||||
signal (svc-gw, recorder, svc-nav, svc-vision, telemetry-gw). Loads keep the car's
|
||||
27 CAN IDs and their rates (2–100 Hz): the capture as recorded, and played 5× faster
|
||||
for a full bus. Signals per frame and a per-signal rate cap (latest value wins)
|
||||
stand in for the decoder design nobody has made yet. 20 s runs.
|
||||
|
||||
| Load | Signals/frame | Cap | Envelopes/s | Deliveries/s (×5) | Broker CPU | Envelope latency p50 / p99 (ms) |
|
||||
|---|---|---|---|---|---|---|
|
||||
| car | 3 | 50 Hz | 1,600 | 8,000 | 22 % | 13 / 21 |
|
||||
| car | 3 | none | 2,550 | 12,800 | 35 % | 13 / 20 |
|
||||
| car | 8 | 20 Hz | 2,550 | 12,800 | 32 % | 14 / 27 |
|
||||
| car | 8 | 50 Hz | 4,300 | 21,600 | 47 % | 16 / 32 |
|
||||
| car | 8 | none | 6,800 | 34,000 | 51 % | 14 / 47 |
|
||||
| full bus | 3 | 50 Hz | 3,100 | 15,500 | 39 % | 12 / 18 |
|
||||
| full bus | 8 | 20 Hz | 3,500 | 17,300 | 44 % | 22 / 41 |
|
||||
| full bus | 8 | 50 Hz | 8,100 | 40,600 | 57 % | 15 / **391** |
|
||||
| full bus | 3 | none | 12,800 | 63,800 | 74 % | **636 / 1,472** |
|
||||
| full bus | 8 | none | 16,300 offered | — | 75 % | **5,380 / 5,994**; decoder queue overflowing |
|
||||
|
||||
- **The raw stream never suffered.** All four raw subscribers got every frame in every
|
||||
run, p99 ≤ 16 ms, including the runs where the envelopes collapsed.
|
||||
- **Envelopes are the load.** The broker's cost follows deliveries (messages ×
|
||||
subscribers). Up to ~22,000 deliveries/s it stays under half a core with p99 near
|
||||
30 ms; around 40,000 the tail goes to hundreds of ms; past ~60,000 queues grow by
|
||||
seconds. Mosquitto is single-threaded, so this is a ceiling, not a share.
|
||||
- **Each subscriber pays too.** Parsing JSON envelopes cost each sink 14–38 % of a
|
||||
core at these rates; five of them took two cores. A real subscriber that takes
|
||||
everything (svc-gw) pays the same.
|
||||
- Envelope loss is not measured exactly (no sequence numbers in the envelope);
|
||||
the decoder's own `refused` counts what it could not even queue.
|
||||
|
||||
What keeps it in the comfortable range, any of which is enough at the car's rate:
|
||||
|
||||
1. **Cap each signal's rate in the decoder**, latest value wins. 20–50 Hz is still
|
||||
10–50× OBD-II polling, and the raw stream keeps the full rate for anything that
|
||||
needs it.
|
||||
2. **Subscribe narrowly.** Only a consumer that shows or stores everything (svc-gw)
|
||||
needs `yukart/vehicle/+`; svc-nav and svc-vision need a handful of topics.
|
||||
3. **Publish slow signals on change**, with a heartbeat; temperatures and states do
|
||||
not need 50 Hz.
|
||||
4. **The recorder need not record decoded signals at full rate.** It records raw
|
||||
frames, and decoding them again offline gives the same signals.
|
||||
|
||||
## Not tested
|
||||
|
||||
- A real CAN adapter: vcan has no bus timing, and the PCAN-USB's own reception and
|
||||
timestamps are already covered by the recorder.
|
||||
- Several subscribers on `yukart/can/raw` at once (recorder reads SocketCAN directly,
|
||||
so expected consumers are the decoder and perhaps svc-gw).
|
||||
- The broker under memory pressure, or with the GPU/vision load of later phases.
|
||||
- The real decoder: signals per frame, rates and topic layout are stand-ins.
|
||||
|
||||
Reference in New Issue
Block a user