Our thread's ID does not change so we don't have to get it every time and hash it every time.
libstdc++-v3/ChangeLog: * include/std/barrier(arrive): move hasher one level up in the stack. --- libstdc++-v3/include/std/barrier | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libstdc++-v3/include/std/barrier b/libstdc++-v3/include/std/barrier index e09212dfcb9..4bb5642c164 100644 --- a/libstdc++-v3/include/std/barrier +++ b/libstdc++-v3/include/std/barrier @@ -94,7 +94,7 @@ It looks different from literature pseudocode for two main reasons: alignas(__phase_alignment) __barrier_phase_t _M_phase; bool - _M_arrive(__barrier_phase_t __old_phase) + _M_arrive(__barrier_phase_t __old_phase, size_t __current) { const auto __old_phase_val = static_cast<unsigned char>(__old_phase); const auto __half_step = @@ -103,9 +103,7 @@ It looks different from literature pseudocode for two main reasons: static_cast<__barrier_phase_t>(__old_phase_val + 2); size_t __current_expected = _M_expected; - std::hash<std::thread::id> __hasher; - size_t __current = __hasher(std::this_thread::get_id()) - % ((_M_expected + 1) >> 1); + __current %= ((__current_expected + 1) >> 1); for (int __round = 0; ; ++__round) { @@ -163,12 +161,14 @@ It looks different from literature pseudocode for two main reasons: [[nodiscard]] arrival_token arrive(ptrdiff_t __update) { + std::hash<std::thread::id> __hasher; + size_t __current = __hasher(std::this_thread::get_id()); __atomic_phase_ref_t __phase(_M_phase); const auto __old_phase = __phase.load(memory_order_relaxed); const auto __cur = static_cast<unsigned char>(__old_phase); for(; __update; --__update) { - if(_M_arrive(__old_phase)) + if(_M_arrive(__old_phase, __current)) { _M_completion(); _M_expected += _M_expected_adjustment.load(memory_order_relaxed); -- 2.30.1