Repository navigation
[TE] Shard TCP transport I/O across a pool of io_context threads - #3724
Merged
Merged
Conversation
anranxia
marked this pull request as ready for review
August 27, 2026 10:06
anranxia
requested review from
alogfans,
chestnut-Q,
doujiang24 and
staryxchen
as code owners
August 27, 2026 10:06
anranxia
force-pushed
the
feat/tcp-io-pool
branch
from
August 27, 2026 11:10
6921768 to
fcb0251
Compare
alogfans
reviewed
Aug 28, 2026
alogfans
reviewed
Aug 28, 2026
staryxchen
reviewed
Aug 28, 2026
anranxia
force-pushed
the
feat/tcp-io-pool
branch
from
August 28, 2026 11:35
fcb0251 to
1009fde
Compare
Contributor
Author
All checks have passed. Whenever you have a moment, could you help merge this? Thanks a lot for the reviews! |
Collaborator
Merged. Thanks for your contribution. |
This was referenced Oct 28, 2026
Open
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
The TCP transfer path currently runs a single
asio::io_contexton one worker thread (TcpTransport::worker→io_context.run()). Every per-peer lane, socket completion, admission timer, and reconnect handler executes on that one thread. On a fast cross-node TCP path (~100 GbE) that single thread saturates at 100% CPU and caps throughput well below line rate — adding more lanes stops helping once they all funnel through the one thread.This PR introduces
TcpIoPool, a bounded pool ofio_contextthreads, and spreads I/O across them while preserving the #2974 bounded-lane model, admission control, reconnect, and exactly-once completion.Design:
TcpIoPoolownsNio_contextinstances, each with its own thread and a work-guard; threads are namedmc-tcp-io-<i>.N = MC_NUM_TCP_IO_THREADS(default 1 = unchanged behavior, bounded [1, 32]).PeerConnectionGroup's coordination state (queue/admission/retry/retirement timers, pump) is pinned to a single shard chosen by hash of the connection key, so itsmutex-guarded state stays serialized on one executor.ConnectionLane's socket, and each accepted server socket, are round-robin bound to a shard (not hashed per-peer), so a single hot peer uses multiple cores.runGroupPumpdispatches a lane's connect/session onto that lane's shard viaasio::dispatch(runs inline when N=1, so the single-thread path is byte-for-byte the previous behavior).Correctness rests on the machinery that already existed for the single-thread path —
PeerConnectionGroup::mutex, theoperation_epoch/pump_epoch/retry_epoch/admission_epochstale-handler guards, and the move-onlyTerminalAction+ClientSession::finalizeexactly-once path. These are mutex/atomic based; they are now genuinely exercised concurrently. Because each socket is pinned to exactly one shard's single-threadedio_context, asio's per-socket handler serialization holds without adding strands.This PR also fixes a pre-existing data race (found while adding TSan coverage):
TcpTransport::getTransferStatusreadtask.transferred_bytes/success_slice_count/failed_slice_countwith plain loads while the I/O thread updates them via__atomic_fetch_add. It now uses__atomic_load_n(..., __ATOMIC_ACQUIRE), matchingMultiTransport::getTransferStatus. This race predates this change (it exists between the single io thread and the polling submission thread).Relates to RFC #1749; builds on the bounded-lane model from #2974.
Module
mooncake-transfer-engine)mooncake-store)mooncake-reshard)mooncake-ep)mooncake-pg)mooncake-integration)mooncake-p2p-store)mooncake-wheel)mooncake-common)mooncake-rl)Type of Change
How Has This Been Tested?
Two cross-node hosts over a ~100 GbE TCP path (data-transfer bytes confirmed to cross the NIC via
/proc/net/dev). Built with-DUSE_CUDA=ON -DBUILD_EXAMPLES=ON.MC_TCP_ENABLE_CONNECTION_POOL=1(default).Regression —
MC_NUM_TCP_IO_THREADS=1is unchanged: cross-node 1 MiB read = 2.49 GB/s, identical to the pre-change baseline; loopback matches too (see below).Cross-node scaling (1 MiB, DRAM read):
WRITE,
N=8lanes=16 threads=4: 12.40 GB/s. Per-thread CPU spreads acrossmc-tcp-io-*instead of one thread at 100%.Loopback, reproducing the #2974 reviewer config (
transfer_engine_bench, threads=4/batch=32/64 KiB/10s):(The baseline 4-lane numbers line up with the #2974 "main 4-lane" measurements, confirming the setup is comparable.)
Correctness —
transfer_engine_validator, cross-node, 12 workers: all 12 workers reportData validation passedat bothMC_NUM_TCP_IO_THREADS=4and=8.ThreadSanitizer: built
-fsanitize=threadand ran the validator (loopback, N=4 and N=8). No data races on the new shared structures (TcpIoPool/PeerConnectionGroup/ConnectionLane) — the existing mutex+epoch model holds under real concurrency. The only transport race TSan reported is the pre-existinggetTransferStatuscounter read (reproducible at N=1), which this PR fixes; after the fix no transport hot-path races remain. (Remaining reports are in the benchmark harness — arunningstop-flag and buffer reuse — and acondition_variableshutdown-tracker report where both sides hold the same mutex.)Test commands:
Test results:
Checklist
./scripts/code_format.shAI Assistance Disclosure
AI (Claude Code) assisted with codebase exploration, drafting the
TcpIoPoolimplementation, and running the benchmark/validator/TSan sweeps. The submitter has reviewed every changed line and can defend the change end-to-end.