Skip to content

perf(reactor): remove the late-round heuristic (CWIST_REACTOR_LATE_US) - #377

Merged
gg582 merged 1 commit into
devfrom
perf/remove-late-round
Oct 14, 2026
Merged

gg582 merged 1 commit into
devfrom
perf/remove-late-round

Conversation

@gg582

@gg582 gg582 commented Oct 14, 2026

Copy link
Copy Markdown
Member

Summary

Removes the late-round heuristic (CWIST_REACTOR_LATE_US, default 3000 us) that bc358b4 added as a #319 experiment.

The heuristic watched each io_uring dispatch round. Once a round had run past the threshold, it switched the rest of that round into late mode:

  • each callback's re-arm was flushed to the kernel right after the callback;
  • posted work was drained after every callback;
  • pipelined HTTP/1.1 connections served their buffered requests without yielding.

Why remove it: the same-runner A/B never showed a tail improvement beyond noise. The follow-up age-based version (#375, now closed) was neutral up to c1024.

Removed

  • src/sys/io/reactor.c:
    • reactor_late_ns() and cwist_reactor_dispatch_late();
    • the per-callback clock read and the late flush/drain;
    • the late_rounds / late_callbacks latency-probe counters.
  • src/sys/io/reactor_rx.h: the cwist_reactor_dispatch_late() declaration and its non-Linux stub.
  • src/sys/app/app.c:
    • the HTTP handler goes back to yielding every yield_batch requests, with no late bypass;
    • the now-unused reactor_rx.h include is gone.
  • tests/test_reactor_late.c and its Makefile target.
  • The CWIST_REACTOR_LATE_US rows in docs/runtime-config.md and docs/ko/runtime-config.md.
  • The "CWIST C1M (late mode off)" benchmark leg in bsd-kqueue-benchmarks.yml, and its mention in scripts/ci/benchmark.py.

Unchanged

  • CWIST_REACTOR_ROUND_BUDGET_US (round-budget flush) and CWIST_REACTOR_DRAIN_CHUNK (post-drain chunking).
  • Past cwist_c1m_lateoff_* rows in benchmarks/webserver.json, kept as history.
  • Public API: this touches only internal headers. check_api_baseline passes.

Verification

  • Full local make test passes on both the default backend and CWIST_REACTOR_BACKEND=epoll.
  • check_test_wiring, check_env_knobs, check_api_baseline and check_inline_exports pass.
  • The workflow YAML parses.

The late-round mode from bc358b4 (issue #319 experiment) switched the rest
of an io_uring dispatch round into a no-yield, flush-per-callback mode once
the round had run past 3 ms. It never showed a tail improvement beyond
noise in the same-runner A/B, and the follow-up age-based variant (#375)
was neutral too. Drop it:

- reactor.c: reactor_late_ns(), cwist_reactor_dispatch_late(), the
  per-callback clock read and late flush, and the late_rounds /
  late_callbacks probe counters;
- reactor_rx.h: the cwist_reactor_dispatch_late() declaration and stub;
- app.c: the HTTP handler yields every yield_batch requests again, with
  no late bypass; the now unused reactor_rx.h include goes too;
- tests/test_reactor_late.c and its Makefile target;
- the CWIST_REACTOR_LATE_US rows in docs/runtime-config.md (en, ko);
- the "CWIST C1M (late mode off)" benchmark leg.

The round-budget flush (CWIST_REACTOR_ROUND_BUDGET_US) and the post-drain
chunking (CWIST_REACTOR_DRAIN_CHUNK) are unchanged. Past cwist_c1m_lateoff
rows in benchmarks/webserver.json stay as history.
@gg582
gg582 merged commit d1339fe into dev Oct 14, 2026
25 checks passed
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.

1 participant