Repository navigation
perf(txpool): poll best transactions' update channel only after the pool sends - #36
Closed
haardikk21 wants to merge 1 commit into
Closed
haardikk21 wants to merge 1 commit into
haardikk21 wants to merge 1 commit into
Conversation
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.
Stacked on #35 (which is stacked on #31); the diff is the last commit only.
Summary
BestTransactions::nextcallsadd_new_transactionsbefore every yield, which callstry_recvon the pending pool's broadcast channel. For tokio's broadcast channel,try_recvon an empty channel takes a read lock on the next slot and then the channel's tail mutex. Senders take the same mutex. The channel is empty for nearly every call, so each yield paid for both locks, and the iterator contended with the pool's insert path on that mutex.PendingPoolnow keeps a sharednew_transaction_count: Arc<AtomicU64>, incremented (Release) after eachsend. EachBestTransactionsfromPendingPool::bestholds the counter and the value it had when the receiver was last found empty.add_new_transactionsloads the counter (Acquire) and only polls the receiver when the counter has moved.try_recvreports nothing left. A burst larger thanMAX_NEW_TRANSACTIONS_PER_BATCHstill drains over the following calls, as before.test_best_receives_more_live_transactions_than_one_batchcovers this.no_updatesdrops the counter along with the receiver.Benchmarks
benches/best_transactions.rs(added in #31), ABBA on a Linux devbox (AMD Ryzen AI MAX+ 395, 32 threads, Linux 7.2, rustc 1.96.0). Each arm was built once and the binaries ran in the order A, B, B, A, pinned to cores 4–15, with 2s warm-up and 5s measurement. A = #35 (c156e4be3), B = this change. Times are means of the A runs and of the B runs, in µs.Each yield saves about 25–30 ns. Taking a snapshot costs about 8 ns more, for the counter's
Arcclone and load, once per iterator. These runs are single-threaded, so they don't show the lock contention between the iterator and concurrent pool inserts that this also removes.Validation
cargo test -p reth-transaction-pool --all-features: 281 unit, 15 integration and 3 doc tests pass.cargo clippy -p reth-transaction-pool --all-features --all-targets -- -D warningscargo +nightly fmt -p reth-transaction-pool -- --check