diff options
Diffstat (limited to 'src/pardes/app.zig')
| -rw-r--r-- | src/pardes/app.zig | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/src/pardes/app.zig b/src/pardes/app.zig index a83485a..23da203 100644 --- a/src/pardes/app.zig +++ b/src/pardes/app.zig @@ -37,6 +37,10 @@ const std = @import("std"); const soc = @import("soc"); const config = @import("config"); + +/// `-Dprof`: time the two phases of a keystroke on the board and print the cycle counts. A +/// diagnostic, not a feature - see the loop. +const prof = config.prof; const hal = @import("hal"); const heapmod = @import("heap"); const uart = @import("uart.zig"); @@ -203,16 +207,36 @@ export fn zig_main() noreturn { var in: [256]u8 = undefined; while (!pardes_p4_quit()) { + // ATTRIBUTION. The host can time a keystroke's round trip but cannot see what the firmware + // spent it on, and the two candidates - parsing and editing, versus rendering - want + // opposite fixes. `soc.cycles()` is the unprivileged cycle counter, so this costs two CSR + // reads per phase and quantises at one cycle, which is four orders of magnitude below the + // milliseconds being attributed. Gated on `prof` so the shipping build carries none of it. const n = uart.read(&in); - if (n > 0) pardes_p4_input(&in, n); + var input_cy: u64 = 0; + if (n > 0) { + const t0 = if (prof) soc.cycles() else 0; + pardes_p4_input(&in, n); + if (prof) input_cy = soc.cycles() - t0; + } pardes_p4_tick(nowMs()); // Only when there is something to show. On a link this slow an unconditional repaint per // iteration would saturate the wire and starve input. if (pardes_p4_wants_frame()) { + const t0 = if (prof) soc.cycles() else 0; const err = pardes_p4_render(); if (err != 0) soc.rom.print("MARK PARDES_RENDER_FAIL rc=%u\r\n", .{err}); + if (prof) { + const render_cy = soc.cycles() - t0; + // Reported in cycles, not microseconds: the divisor is the CPU clock, which this + // firmware does not set and has only ever measured, so converting here would bake a + // guess into the data. `experiments/` divides by the clock it measured. + soc.rom.print("PROF in=%u render=%u\r\n", .{ + @as(u32, @intCast(input_cy)), @as(u32, @intCast(render_cy)), + }); + } } } |
