Skip to content
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

thread: optimize maybe_yield #2574

Merged
merged 1 commit into from
Dec 11, 2024

Conversation

travisdowns
Copy link
Contributor

@travisdowns travisdowns commented Dec 11, 2024

thread::maybe_yield, a static method, calls into
thread_impl::maybe_yield which is a member function on the current thread context, which means we need to access the TLS etc, but this function is itself essentially static as it only calls needs_prempt().

This was probably different in the ancient past where there were thread-specific scheduling groups, etc.

This method is performance sensitive as it is often called in loops, even tight loops as it is often difficult to call it less frequently in a tight loop which may have a large trip count. Therefore it is worth optimizing.

So this change:

  • Have thread::maybe_yield just call needs_prempt() directly
  • Move maybe_yield and should_yield in to the header.

This latter change doesn't change needed includes, so shouldn't impact compile time. The yield() function itself is still out-of-line. This provides a chance for the compile to hoist the TLS access boilerplate out of loops.

I also add an [[unlikely]] annotation in the direction of "not yielding".

thread::maybe_yield, a static method, calls into
thread_impl::maybe_yield which is a member function on the current
thread context, which means we need to access the TLS etc, but this
function is itself essentially static as it only calls needs_prempt().

This was probably different in the ancient past where there were
thread-specific scheduling groups, etc.

This method is performance sensitive as it is often called in loops,
even tight loops as it is often difficult to call it less frequently
in a tight loop which may have a large trip count. Therefore it is
worth optimizing.

So this change:

 - Have thread::maybe_yield just call needs_prempt() directly
 - Move maybe_yield and should_yield in to the header.

This latter change doesn't change needed includes, so shouldn't impact
compile time. The yield() function itself is still out-of-line. This
provides a chance for the compile to hoist the TLS access boilerplate
out of loops.
@travisdowns
Copy link
Contributor Author

This came up while looking at metrics endpoint performance but decided to split it out alone since it's not really specific to metrics.


/// \brief Yield if this thread ought to call yield() now.
///
/// Useful where a code does long running computation and does
/// not want to hog cpu for more then its share
static void maybe_yield();
static void maybe_yield() {
if (should_yield()) [[unlikely]] {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: unlikely is unnecessary (but not harmful) since need_preempt() is annotated with __builtin_expect.

@avikivity avikivity merged commit 2bba120 into scylladb:master Dec 11, 2024
15 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.

2 participants