summaryrefslogtreecommitdiff
path: root/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'README.md')
-rw-r--r--README.md46
1 files changed, 46 insertions, 0 deletions
diff --git a/README.md b/README.md
index 181ec0e..33fc3f5 100644
--- a/README.md
+++ b/README.md
@@ -9,6 +9,7 @@ zig build console # attach a terminal to whatever is already on the board (Ct
zig build interact # flash, then attach that terminal (ordered, like `run`)
zig build reset # just pulse the reset line
zig build size # where every byte of the image went
+zig build bench # measure the serial link and the editor, verified with a checksum
zig build test # host tests: image builder, and the register layer's field arithmetic
zig build diff # the hardware oracle: this HAL vs ESP-IDF's, on the die (needs -Doracle)
zig build elf # stop at the ELF, for disassembly
@@ -121,6 +122,51 @@ Measured on ESP32-P4 rev v1.3 silicon: two `Peek`s of the RNG register at `0x501
`Peek 0x50110001` answered `peek: MisalignedAddress` on the message row rather than taking the
session down with an unhandled trap, which is the one fault that file exists to prevent.
+### Measuring it
+
+`p4-bench` exists so that optimising this port is not a matter of opinion. It has two halves,
+because there are two different questions.
+
+```
+zig build flash -Dapp=examples/uartperf.zig # the ceiling: link + driver, nothing else
+zig-out/bin/p4-bench --link
+
+zig build flash -Dpardes # how much of that ceiling the editor uses
+zig-out/bin/p4-bench --editor
+zig-out/bin/p4-bench --sweep length --repeat 7 --csv --label ReleaseSmall
+```
+
+Every `--link` number is checksummed. `tools/perfproto.zig` is a framed protocol - `"P4"`, op,
+length, CRC-32, payload - shared *verbatim* by the host tool and `examples/uartperf.zig`, so a frame
+one writes and the other parses cannot drift. That matters because RX overrun on this UART is
+undetected in hardware and uncounted in the driver: a byte that never arrived is indistinguishable
+from a late one, and an unchecksummed throughput figure is a guess about how fast data was corrupted.
+
+`tools/rtt.zig` holds the two timing functions everything is built on. Round trip is measured to the
+**first** response byte, not the last: a renderer that starts drawing in 8 ms and finishes in 130 ms
+feels immediate, one that thinks for 130 ms then draws in 8 ms feels broken, and waiting for the wire
+to fall quiet cannot tell them apart. Time to the last byte is recorded separately as `settle`.
+Microseconds throughout, because at 115200 one byte is 87 us and a millisecond clock would quantise
+the answer into buckets eleven bytes wide.
+
+`experiments/` holds the raw per-trial CSVs and `report.typ`, which reads them and computes its own
+figures - so a re-run changes the document rather than contradicting it. What it establishes on this
+die:
+
+| | |
+|---|---|
+| link, both directions | 99.8% of the 11,520 B/s wire, CRC verified over 32,768 B |
+| typing, 6 to 100 keys/s | nothing lost, wire never above 9% |
+| one keystroke | 81 B, round trip 17.0 ms |
+| a motion | 40 B, round trip 16.7 ms |
+| cost per character already in the line | **54.3 us, per keystroke** |
+
+The first two rows say the wire is not the problem. The last three say why: a 40-byte operation and a
+206-byte one cost the same round trip, so latency is compute per event and not transmission - and it
+grows with the document, because the edit path copies the whole buffer every keystroke. Building the
+editor object `ReleaseFast` instead of `ReleaseSmall` cuts the fixed cost 13% and the per-character
+cost 36% for 35% more flash, which is the best ratio measured here.
+
## Layout
```