- Sponsor
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Reduce contention in watch channel #5464
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
We need the `Notified` future to be created before the first poll. Otherwise, we wont catch `notify_waiters` calls between the creation and first poll of the future.
/// This function implements the case where randomness is not available. | ||
#[cfg(not(all(not(loom), feature = "sync", any(feature = "rt", feature = "macros"))))] | ||
pub(super) fn notified(&self) -> Notified<'_> { | ||
let i = self.next.fetch_add(1, Relaxed) % 8; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you use TaskID here or something similar? Not a big deal either way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't use task or thread ids here, because they require the context thread-local to be available, which it isn't when we use the fallback.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, we probably should at least track the benchmarks that led to this change somewhere for future reference.
@tijsvd Would you be willing to submit a PR that adds your benchmark to Tokio's benchmarks? |
Yes I'll look into it. I'm now looking at some weird effects in a changed version of this benchmark, where it looks like the time of the sleep between test runs hugely influences the outcome. Positive results of this PR are still measurable, but I want to understand this sleep effect better before submitting anything. |
Ok, the sleep time influences the test run just because of CPU frequency stepping. And because it ran so fast, I increased the amount of "work" by a factor of 10. Now when running the test hot, I could hardly measure a difference between pre and post PR. This was due to the probability of mutex contention being lower and/or the effect of contention being smaller. Bringing back the amount of work to its original allows for running the test hot (criterion style), and shows a significant improvement in this PR (the variant with pre-allocated waker slots still outperforms it by a margin). |
I saw quite a bit of variance running benches; you might want to check moving to Criterion instead, it's generally a straightforward conversion. In my experience, Criterion outcomes are a bit more stable due to proper warm-up. |
# 1.26.0 (March 1st, 2023) ### Fixed - sync: don't leak tracing spans in mutex guards ([#5469]) - sync: drop wakers after unlocking the mutex in Notify ([#5471]) - sync: drop wakers outside lock in semaphore ([#5475]) - macros: fix empty `join!` and `try_join!` ([#5504]) ### Added - fs: add `fs::try_exists` ([#4299]) - net: add types for named unix pipes ([#5351]) - sync: add `MappedOwnedMutexGuard` ([#5474]) ### Documented - task: clarify what happens to spawned work during runtime shutdown ([#5394]) - task: clarify `process::Command` docs (#5406) ([#5413]) - sync: add doc aliases for `blocking_*` methods ([#5448]) - task: fix wording with 'unsend' ([#5452]) - signal: updated Documentation for Signals ([#5459]) - sync: fix docs for Send/Sync bounds in broadcast ([#5480]) - io: improve AsyncFd example ([#5481]) - tokio: document supported platforms ([#5483]) - runtime: document the nature of the main future ([#5494]) - sync: document drop behavior for channels ([#5497]) - time: document immediate completion guarantee for timeouts ([#5509]) - runtime: remove extra period in docs ([#5511]) ### Changed - net: use Message Read Mode for named pipes ([#5350]) - chore: update windows-sys to 0.45 ([#5386]) - sync: mark lock guards with `#[clippy::has_significant_drop]` ([#5422]) - sync: reduce contention in watch channel ([#5464]) - time: remove cache padding in timer entries ([#5468]) - time: Improve `Instant::now()` perf with test-util ([#5513]) ### Internal Changes - tests: port proptest fuzz harnesses to use cargo-fuzz ([#5392]) - time: don't store deadline twice in sleep entries ([#5410]) - rt: remove Arc from Clock ([#5434]) - sync: make `notify_waiters` calls atomic ([#5458]) - net: refactor named pipe builders to not use bitfields ([#5477]) - io: use `poll_fn` in `copy_bidirectional` ([#5486]) - fs: add more tests for filesystem functionality ([#5493]) - net: fix test compilation failure ([#5506]) - io: ignore SplitByUtf8BoundaryIfWindows test on miri ([#5507]) ### Unstable - metrics: add a new metric for budget exhaustion yields ([#5517]) [#4299]: #4299 [#5350]: #5350 [#5351]: #5351 [#5386]: #5386 [#5392]: #5392 [#5394]: #5394 [#5410]: #5410 [#5413]: #5413 [#5422]: #5422 [#5434]: #5434 [#5448]: #5448 [#5452]: #5452 [#5458]: #5458 [#5459]: #5459 [#5464]: #5464 [#5468]: #5468 [#5469]: #5469 [#5471]: #5471 [#5474]: #5474 [#5475]: #5475 [#5477]: #5477 [#5480]: #5480 [#5481]: #5481 [#5483]: #5483 [#5486]: #5486 [#5493]: #5493 [#5494]: #5494 [#5497]: #5497 [#5504]: #5504 [#5506]: #5506 [#5507]: #5507 [#5509]: #5509 [#5511]: #5511 [#5513]: #5513 [#5517]: #5517
# 1.26.0 (March 1st, 2023) ### Fixed - macros: fix empty `join!` and `try_join!` ([#5504]) - sync: don't leak tracing spans in mutex guards ([#5469]) - sync: drop wakers after unlocking the mutex in Notify ([#5471]) - sync: drop wakers outside lock in semaphore ([#5475]) ### Added - fs: add `fs::try_exists` ([#4299]) - net: add types for named unix pipes ([#5351]) - sync: add `MappedOwnedMutexGuard` ([#5474]) ### Changed - chore: update windows-sys to 0.45 ([#5386]) - net: use Message Read Mode for named pipes ([#5350]) - sync: mark lock guards with `#[clippy::has_significant_drop]` ([#5422]) - sync: reduce contention in watch channel ([#5464]) - time: remove cache padding in timer entries ([#5468]) - time: Improve `Instant::now()` perf with test-util ([#5513]) ### Internal Changes - io: use `poll_fn` in `copy_bidirectional` ([#5486]) - net: refactor named pipe builders to not use bitfields ([#5477]) - rt: remove Arc from Clock ([#5434]) - sync: make `notify_waiters` calls atomic ([#5458]) - time: don't store deadline twice in sleep entries ([#5410]) ### Unstable - metrics: add a new metric for budget exhaustion yields ([#5517]) ### Documented - io: improve AsyncFd example ([#5481]) - runtime: document the nature of the main future ([#5494]) - runtime: remove extra period in docs ([#5511]) - signal: updated Documentation for Signals ([#5459]) - sync: add doc aliases for `blocking_*` methods ([#5448]) - sync: fix docs for Send/Sync bounds in broadcast ([#5480]) - sync: document drop behavior for channels ([#5497]) - task: clarify what happens to spawned work during runtime shutdown ([#5394]) - task: clarify `process::Command` docs ([#5413]) - task: fix wording with 'unsend' ([#5452]) - time: document immediate completion guarantee for timeouts ([#5509]) - tokio: document supported platforms ([#5483]) [#4299]: #4299 [#5350]: #5350 [#5351]: #5351 [#5386]: #5386 [#5394]: #5394 [#5410]: #5410 [#5413]: #5413 [#5422]: #5422 [#5434]: #5434 [#5448]: #5448 [#5452]: #5452 [#5458]: #5458 [#5459]: #5459 [#5464]: #5464 [#5468]: #5468 [#5469]: #5469 [#5471]: #5471 [#5474]: #5474 [#5475]: #5475 [#5477]: #5477 [#5480]: #5480 [#5481]: #5481 [#5483]: #5483 [#5486]: #5486 [#5494]: #5494 [#5497]: #5497 [#5504]: #5504 [#5509]: #5509 [#5511]: #5511 [#5513]: #5513 [#5517]: #5517
# 1.26.0 (March 1st, 2023) ### Fixed - macros: fix empty `join!` and `try_join!` ([#5504]) - sync: don't leak tracing spans in mutex guards ([#5469]) - sync: drop wakers after unlocking the mutex in Notify ([#5471]) - sync: drop wakers outside lock in semaphore ([#5475]) ### Added - fs: add `fs::try_exists` ([#4299]) - net: add types for named unix pipes ([#5351]) - sync: add `MappedOwnedMutexGuard` ([#5474]) ### Changed - chore: update windows-sys to 0.45 ([#5386]) - net: use Message Read Mode for named pipes ([#5350]) - sync: mark lock guards with `#[clippy::has_significant_drop]` ([#5422]) - sync: reduce contention in watch channel ([#5464]) - time: remove cache padding in timer entries ([#5468]) - time: Improve `Instant::now()` perf with test-util ([#5513]) ### Internal Changes - io: use `poll_fn` in `copy_bidirectional` ([#5486]) - net: refactor named pipe builders to not use bitfields ([#5477]) - rt: remove Arc from Clock ([#5434]) - sync: make `notify_waiters` calls atomic ([#5458]) - time: don't store deadline twice in sleep entries ([#5410]) ### Unstable - metrics: add a new metric for budget exhaustion yields ([#5517]) ### Documented - io: improve AsyncFd example ([#5481]) - runtime: document the nature of the main future ([#5494]) - runtime: remove extra period in docs ([#5511]) - signal: updated Documentation for Signals ([#5459]) - sync: add doc aliases for `blocking_*` methods ([#5448]) - sync: fix docs for Send/Sync bounds in broadcast ([#5480]) - sync: document drop behavior for channels ([#5497]) - task: clarify what happens to spawned work during runtime shutdown ([#5394]) - task: clarify `process::Command` docs ([#5413]) - task: fix wording with 'unsend' ([#5452]) - time: document immediate completion guarantee for timeouts ([#5509]) - tokio: document supported platforms ([#5483]) [#4299]: #4299 [#5350]: #5350 [#5351]: #5351 [#5386]: #5386 [#5394]: #5394 [#5410]: #5410 [#5413]: #5413 [#5422]: #5422 [#5434]: #5434 [#5448]: #5448 [#5452]: #5452 [#5458]: #5458 [#5459]: #5459 [#5464]: #5464 [#5468]: #5468 [#5469]: #5469 [#5471]: #5471 [#5474]: #5474 [#5475]: #5475 [#5477]: #5477 [#5480]: #5480 [#5481]: #5481 [#5483]: #5483 [#5486]: #5486 [#5494]: #5494 [#5497]: #5497 [#5504]: #5504 [#5509]: #5509 [#5511]: #5511 [#5513]: #5513 [#5517]: #5517
See discussion in #5403 for context.
cc @tijsvd
Closes: #5403