Skip to content

feat(net): thread-per-core I/O (SO_REUSEPORT) — beats glommio across the connection spectrum - #2

Merged
mash180sx merged 3 commits into
mainfrom
feat/io-thread-per-core
Jul 18, 2026
Merged

feat(net): thread-per-core I/O (SO_REUSEPORT) — beats glommio across the connection spectrum#2
mash180sx merged 3 commits into
mainfrom
feat/io-thread-per-core

Conversation

@mash180sx

Copy link
Copy Markdown
Contributor

What

Adds thread-per-core network serving to the net feature: serve_on_cores(addr, cores, factory, opts) runs one busy-poll reactor per core, each with its own SO_REUSEPORT listener so the kernel spreads connections across cores. This is AetherFlow's thread-per-core thesis applied to I/O — directly comparable to glommio's N executors.

  • serve_on_cores + reuseport_listener (socket2); ServerHandle generalized to N reactors
  • io_bench gains multi-core server (0,1,.. core CSV) and a panic-free client (tolerates fd/backlog limits at high conns, small worker stacks)
  • echo_glommio gains multi-executor mode (LocalExecutorPoolBuilder + reuseport)
  • New test multicore_reuseport_echo

Measured — N-vs-N scale (AWS c7g.4xlarge, 16 vCPU; server cores 0–7 / client cores 8–15)

AetherFlow busy-poll scan (8 reactors) vs glommio (8 io_uring executors), 32B echo:

conns AF scan p50 / p99 / thru glommio p50 / p99 / thru
256 168µs / 330µs / 500k 208 / 418 / 466k
1024 457µs / 1180µs / 587k 777 / 1192 / 479k
4096 362µs / 890µs / 643k 4237 / 4793 / 437k
8192 408µs / 2036µs / 620k 9306 / 10071 / 414k

AF scan wins median, tail, and throughput at every connection count, and the gap widens at scale — at 8192 conns: median ~23×, throughput ~1.5×, p99 ~5×. This refutes the earlier worry that high-concurrency belongs to io_uring/readiness: on dedicated cores, thread-per-core busy-poll scales better (park/wake wakeup latency inflates glommio's median under high fan-in). The epoll backend regresses at high conns — scan busy-poll is the winner; default stays scan.

Honesty

  • busy-poll burns 100% of its cores regardless of load (latency↔CPU tradeoff — dedicated-core premise).
  • localhost, one run per point, client co-located (cores isolated); default glommio config + straightforward echo. Real-network / multi-run / variance are follow-ups.
  • Feature net remains default-OFF; published default API unchanged.

Full detail: docs/io-surface-design.md §7.6.

🤖 Generated with Claude Code

mash180sx and others added 3 commits July 18, 2026 23:45
- serve_on_cores(addr, cores, factory, opts): コアごと 1 reactor + SO_REUSEPORT listener。
  カーネルが着信を各 listener に分散 = thread-per-core I/O(glommio の N executor と N対N比較用)。
  socket2 で reuse_port。ServerHandle は複数 reactor を保持するよう一般化。
- io_bench aether-server: コア csv 指定(単一=serve_with / 複数=serve_on_cores)。client を
  堅牢化(接続/送受信失敗で panic せず打ち切り・失敗数を表示)= 高並行で fd/backlog 上限でも落ちない。
- echo_glommio: 複数コア(LocalExecutorPoolBuilder N shard + reuseport)対応 = N対N。
- 新テスト multicore_reuseport_echo(2 reactor + 8 client)緑。macOS も SO_REUSEPORT 可。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…92)で全指標勝ち

16 vCPU(server 8コア/client 8コア)で AF scan(8 reactor+SO_REUSEPORT)vs glommio(8 executor)。
conns 256→8192 で中央値・tail・throughput すべて AF 勝ち、差はスケールで拡大(8192で中央値 408µs
vs glommio 9306µs=23x, throughput 620k vs 414k=1.5x, p99 2.0ms vs 10.1ms=5x)。前回保留の高並行側は
thread-per-core で決着(勝ち)。epoll は高並行で退行=不要、勝ち筋は scan busy-poll。
但し書き: busy-poll は 8コア100%(latency↔CPU)、localhost・各点1回・glommio 既定設定。
@mash180sx
mash180sx merged commit c53866e into main Jul 18, 2026
3 checks passed
@mash180sx
mash180sx deleted the feat/io-thread-per-core branch July 18, 2026 14:58
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