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

Performance defect in disruptorplus::spin_wait ctor #5

Open
pkarneliuk opened this issue Apr 26, 2024 · 0 comments
Open

Performance defect in disruptorplus::spin_wait ctor #5

pkarneliuk opened this issue Apr 26, 2024 · 0 comments

Comments

@pkarneliuk
Copy link

The constructor of class disruptorplus::spin_wait has the call to std::thread::hardware_concurrency(). It affects latency of all
disruptorplus::spin_wait_strategy::wait_until_published() methods:

spin_wait()
{
reset();
}
/// \brief
/// Reset the spin_wait back to its original state.
void reset()
{
m_value = std::thread::hardware_concurrency() > 1 ? 0 : 10;
}

sequence_t wait_until_published(
sequence_t sequence,
size_t count,
const std::atomic<sequence_t>* const sequences[])
{
assert(count > 0);
spin_wait spinner;
sequence_t result = minimum_sequence_after(sequence, count, sequences);
while (difference(result, sequence) < 0)
{
spinner.spin_once();
result = minimum_sequence_after(sequence, count, sequences);
}
return result;
}

template<typename Clock, typename Duration>
sequence_t wait_until_published(
sequence_t sequence,
size_t count,
const std::atomic<sequence_t>* const sequences[],
const std::chrono::time_point<Clock, Duration>& timeoutTime)
{
assert(count > 0);
spin_wait spinner;
sequence_t result = minimum_sequence_after(sequence, count, sequences);
while (difference(result, sequence) < 0)
{
if (spinner.next_spin_will_yield() && timeoutTime < Clock::now())
{
// Out of time.
return result;
}
spinner.spin_once();
result = minimum_sequence_after(sequence, count, sequences);
}
return result;
}

Also, there are some redundant code which trying to hide negative impact of this defect:

size_t count = m_sequences.size();
sequence_t current = minimum_sequence_after(sequence, count, m_sequences.data());
if (difference(current, sequence) >= 0)
{
return current;
}

size_t count = m_sequences.size();
sequence_t current = minimum_sequence_after(sequence, count, m_sequences.data());
if (difference(current, sequence) >= 0)
{
return current;
}

Possible fix is to save the result of std::thread::hardware_concurrency() in some static variable and reuse it in spin_wait ctor.

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

No branches or pull requests

1 participant