diff mbox series

[5/5] barrier: optimise by not having the hasher in a loop

Message ID 20210226155937.621324-5-thiago.macieira@intel.com
State New
Headers show
Series [1/5] std::latch: reduce internal implementation from ptrdiff_t to int | expand

Commit Message

Thiago Macieira Feb. 26, 2021, 3:59 p.m. UTC
Our thread's ID does not change so we don't have to get it every time
and hash it every time.
---
 libstdc++-v3/include/std/barrier | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

Comments

Jonathan Wakely March 3, 2021, 2:36 p.m. UTC | #1
On 26/02/21 07:59 -0800, Thiago Macieira via Libstdc++ wrote:
>Our thread's ID does not change so we don't have to get it every time
>and hash it every time.

This looks good for GCC 11.

(This one wouldn't be an ABI break to change later, but we might as
well do it now, as we have the patch now).


> 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 ae058bd3dc3..eb31a89b175 100644
>--- a/libstdc++-v3/include/std/barrier
>+++ b/libstdc++-v3/include/std/barrier
>@@ -101,12 +101,10 @@ It looks different from literature pseudocode for two main reasons:
>       }
>
>       bool
>-      _M_arrive(__barrier_phase_t __old_phase)
>+      _M_arrive(__barrier_phase_t __old_phase, size_t __current)
>       {
> 	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);
>
> 	const auto __half_step = _S_add_to_phase(__old_phase, 1);
> 	const auto __full_step = _S_add_to_phase(__old_phase, 2);
>@@ -167,11 +165,13 @@ 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);
> 	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
>
diff mbox series

Patch

diff --git a/libstdc++-v3/include/std/barrier b/libstdc++-v3/include/std/barrier
index ae058bd3dc3..eb31a89b175 100644
--- a/libstdc++-v3/include/std/barrier
+++ b/libstdc++-v3/include/std/barrier
@@ -101,12 +101,10 @@  It looks different from literature pseudocode for two main reasons:
       }
 
       bool
-      _M_arrive(__barrier_phase_t __old_phase)
+      _M_arrive(__barrier_phase_t __old_phase, size_t __current)
       {
 	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);
 
 	const auto __half_step = _S_add_to_phase(__old_phase, 1);
 	const auto __full_step = _S_add_to_phase(__old_phase, 2);
@@ -167,11 +165,13 @@  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);
 	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);