Skip to content

Simulator speed and responsiveness overhaul#22

Merged
terjeio merged 1 commit into
grblHAL:masterfrom
gcormier:finaloptimize
Jul 12, 2026
Merged

Simulator speed and responsiveness overhaul#22
terjeio merged 1 commit into
grblHAL:masterfrom
gcormier:finaloptimize

Conversation

@gcormier

Copy link
Copy Markdown
Contributor

The goal was to speed up the simulator, such that local developer on senders (gSender in my case) was better.

The intent was to avoid any functional errors, but I'm NOT using the simulator to test any step timings.

I have ONLY tested on Windows. The result is a much more responsive gSender, useful for testing various gSender improvements I am working on.

If desireable, I can

  1. Break up changes into smaller PR's and/or
  2. Allow for compile time options, to keep the older(slower) but "tested" version, and only build the performance optimized versions for people with use cases like myself with compile flags.

Throughput: -O0 baseline to event-driven clock

Batch of five optimizations, verified byte-identical against the pre-change
build on the plan workload:

  1. Build at -O3 by default (was compiling at -O0 with no
    CMAKE_BUILD_TYPE). 1.8x end-to-end, zero code change. Landed with the
    volatile shared-state fixes it depends on.
  2. Event-driven clock: sim_loop/mcu_master_clock now jump
    masterclock straight to the next event (timer expiry, systick, serial
    byte, target) instead of iterating all 16M ticks per simulated second.
    Idle periods become free. Benchmark 0.90s to 0.02s; ISR interval trace
    verified identical (32,857 firings, 0 mismatches).
  3. Per-tick micro-fixes: lazy sim_time, early bail in print_steps,
    timer bitmask + gpio_irq_pending flag + direct ISR dispatch.
  4. Stop the grbl thread burning a full core: sched_yield() in the
    realtime hook and delay spin loop.
  5. Serial polling syscall diet: raw terminal set up once, non-blocking
    read() for stdin/socket polling.

Interactive latency: chunky/unresponsive sender realtime view

Fixed three independent, compounding problems behind gSender's chunky
DRO/visualizer over -p <port>:

  • TCP_NODELAY on the accepted socket, plus flush-on-\n-only so each
    status report goes out as one segment (kills Nagle + delayed-ACK stalls
    that quantized the view to the poll rate, up to ~200ms on Windows).
  • Control frame 100ms to 20ms for lower structural input latency.
  • Windows console fixes: timeBeginPeriod(1) for accurate frame sleeps,
    QuickEdit disabled so a stray click can no longer freeze the sim,
    throttled _kbhit, and block output no longer written to stdout in socket
    mode.

Measured ? to status-report latency (Linux, loopback): p50 46ms to 6.8ms,
p90 51ms to 9.7ms, max 90ms to 27ms. Windows-only wins (delayed-ACK,
QuickEdit freezes, Sleep granularity) come on top and need eyeball
verification in gSender.

Behavior change

With -p and no -b, per-block lines are no longer printed to stdout. Pass
-b <file> to keep them.

Regression

Serial and block output byte-identical pre/post on the plan workload.
-r 0.01 step trace differs only by a documented sampling-boundary artifact
(last-digit timestamps, +/-1 step at sample boundaries; final position
identical). -t 1 pacing confirmed (5.07s wall for 5.07s simulated).

Consolidates the optimizer work into a single change:

- Event-driven master clock that skips provably idle ticks.
- Per-tick micro-fixes in the hardware simulator hot path: lazy sim_time,
  early bail in print_steps, timer-enabled bitmask and direct ISR dispatch.
- Serial polling syscall diet: one-time raw setup plus non-blocking read.
- Yield the host CPU instead of busy-spinning the grbl thread.
- Default to -O3 Release builds, with the cross-thread data races that
  optimization exposed fixed.
- Add -v/--version reporting build-time info.
- Fix chunky/unresponsive sender realtime view in socket mode.

grbl/block output is byte-identical to before; -r sampling drift is bounded.
@terjeio

terjeio commented Jul 12, 2026

Copy link
Copy Markdown
Contributor
    • if someone wants the old behaviour then report back to make it a compile time option

@terjeio
terjeio merged commit 25a545e into grblHAL:master Jul 12, 2026
4 checks passed
@gcormier
gcormier deleted the finaloptimize branch July 12, 2026 17:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants