summaryrefslogtreecommitdiff
path: root/experiments/report.typ
diff options
context:
space:
mode:
Diffstat (limited to 'experiments/report.typ')
-rw-r--r--experiments/report.typ57
1 files changed, 50 insertions, 7 deletions
diff --git a/experiments/report.typ b/experiments/report.typ
index 8ed2b07..8134db2 100644
--- a/experiments/report.typ
+++ b/experiments/report.typ
@@ -42,9 +42,14 @@
}
#let length_rows = rows("length-ReleaseSmall.csv") + rows("length-ReleaseFast.csv")
+ + rows("length-ReleaseSmall-lineSpan.csv") + rows("length-ReleaseFast-lineSpan.csv")
#let ops_rows = rows("ops-ReleaseSmall.csv") + rows("ops-ReleaseFast.csv")
+// Figure 1 compares the two optimisation modes only; the `lineSpan` variants are the SAME source
+// change applied to each, and are tabulated separately in Experiment 3 rather than plotted, because
+// four indistinguishable pairs of lines would be a worse picture than two.
#let builds = ("ReleaseSmall", "ReleaseFast")
+#let all_builds = ("ReleaseSmall", "ReleaseSmall-lineSpan", "ReleaseFast", "ReleaseFast-lineSpan")
#let lengths = (0, 20, 40, 80, 160)
#let med_rtt(rs, pred) = median(rs.filter(pred).map(r => r.rtt))
@@ -419,13 +424,51 @@ independent runs:
1.00×, which is stronger evidence than any single cell.],
)
-And on the board it changed *nothing*: the slope was
-#calc.round(fit(lengths.map(l => l * 1.0), lengths.map(l => med_rtt(length_rows, r => r.label == "ReleaseSmall" and r.length == l))).slope * 1000, digits: 1) µs
-per character before and 54.0 µs after, a ratio of 1.00. That is not a
-contradiction, it is the same fact seen twice: the removed passes are $O(#h(0.1em)$document$)$,
-and this board's document is a few hundred *bytes*, so two scans of it cost nothing
-worth measuring. The identical change is worth 20% on a 19 MB file and 0% on a
-240-character one.
+And on the board it changed *nothing*, in either optimisation mode. All four
+combinations were measured on the die, 5 lengths × 7 trials each:
+
+#figure(
+ table(
+ columns: (auto, auto, auto, auto, auto),
+ align: (left, right, right, right, right),
+ stroke: none,
+ table.hline(),
+ table.header([configuration], [fixed cost], [per character], [at 160 chars], [vs baseline]),
+ table.hline(stroke: 0.5pt),
+ ..all_builds.map(b => {
+ let xs = lengths.map(l => l * 1.0)
+ let ys = lengths.map(l => med_rtt(length_rows, r => r.label == b and r.length == l))
+ let f = fit(xs, ys)
+ let at160 = ys.last()
+ let ref160 = med_rtt(length_rows, r => r.label == "ReleaseSmall" and r.length == 160)
+ (
+ raw(b),
+ [#calc.round(f.intercept, digits: 2) ms],
+ [#calc.round(f.slope * 1000, digits: 1) µs],
+ [#calc.round(at160, digits: 2) ms],
+ [#calc.round(at160 / ref160, digits: 2)×],
+ )
+ }).flatten(),
+ table.hline(),
+ ),
+ caption: [The edit-path change is invisible in both modes; the optimisation mode
+ is the whole of the difference. `ReleaseFast` + `lineSpan` is indistinguishable
+ from `ReleaseFast` alone.],
+)
+
+That is not a contradiction, it is the same fact seen twice: the removed passes are
+$O(#h(0.1em)$document$)$, and this board's document is a few hundred *bytes*, so two
+scans of it cost nothing worth measuring. The identical change is worth 20% on a
+19 MB file and 0% on a 240-character one.
+
+The measurement did change one thing about the board, though, and it is not the
+source: `-Doptimize` defaulted to `Debug`, so a plain `zig build -Dplatform=p4`
+produced an object that *cannot run* — `Debug` wraps every tier in `allocators.zig`
+in a `DebugAllocator` whose metadata is page-granular, and one 4 KiB page per size
+class does not fit in the 384 KiB the board hands over. The p4 target now defaults to
+`ReleaseFast`, which is the mode this experiment chose rather than a preference, and
+an explicit `-Doptimize=` still wins. The 21% is therefore what the default build now
+gives, not something to remember to ask for.
The lesson is the one the instrument exists to enforce. A plausible mechanism, read
off the source and consistent with the shape of the data, was wrong about where the