[PATCH 1/2] Optimize generic spinlock code and use C11 like atomic macros.
Stefan Liebler
stli@linux.vnet.ibm.com
Thu Mar 23 16:16:00 GMT 2017
On 03/22/2017 01:56 PM, Szabolcs Nagy wrote:
> On 21/03/17 15:43, Stefan Liebler wrote:
>> On 03/14/2017 04:55 PM, Stefan Liebler wrote:
>>> Okay. I've attached an updated patch. It is now using case 2).
>>> This choice applies to pthread_spin_trylock.c and the first attempt to
>>> acquire the lock in pthread_spin_lock.c.
>>> Therefore I've introduced ATOMIC_EXCHANGE_USES_CAS for all architectures
>>> in atomic-machine.h files. There is a check in include/atomic.h which
>>> ensures that it is defined to either 0 or 1. Can you please review the
>>> setting of 0 or 1?
>>>
>>> Bye Stefan
>> Ping
>>
>
> the aarch64 changes look ok to me (but this is
> something that ideally would be benchmarked on real
> hw with interesting workload and i haven't done that
> because it is non-trivial)
>
> on a trivial benchmark it seems to be a bit better
> than the current code.
>
This sounds good.
> the performance of the unconteded case can be improved
> slightly by reverting the unlock change (the release
> store is stronger than the barrier was, conceptually
> there is a barrier before and after an armv8 release
> store to prevent an independent load-acquire to get
> reordered with it in either direction)
>
Thus you mean something like the following?
atomic_thread_fence_release ();
atomic_store_relaxed (lock, 0);
(Info: I've used scripts/build-many-glibcs.py to get the following
objdumps. The sysdeps/powerpc/nptl/pthread_spin_unlock.c is using
atomic_store_release, too. For the following powerpc64-linux-gnu
objdumps, I've removed the powerpc-spinlock implementation to see the
differences)
=>aarch64-linux-gnu
0000000000000000 <pthread_spin_unlock>:
0: d5033bbf dmb ish
4: b900001f str wzr, [x0]
8: 52800000 mov w0, #0x0 // #0
c: d65f03c0 ret
=>powerpc64-linux-gnu:
0000000000000000 <.pthread_spin_unlock>:
0: 7c 69 1b 78 mr r9,r3
4: 7c 20 04 ac lwsync
8: 39 40 00 00 li r10,0
c: 38 60 00 00 li r3,0
10: 91 49 00 00 stw r10,0(r9)
14: 4e 80 00 20 blr
Here is the upstream code as comparison:
atomic_full_barrier ();
*lock = 0;
=>aarch64-linux-gnu
0000000000000000 <pthread_spin_unlock>:
0: aa0003e1 mov x1, x0
4: d5033bbf dmb ish
8: 52800000 mov w0, #0x0 // #0
c: b900003f str wzr, [x1]
10: d65f03c0 ret
=>powerpc64-linux-gnu:
0000000000000000 <.pthread_spin_unlock>:
0: 7c 69 1b 78 mr r9,r3
4: 7c 00 04 ac hwsync
8: 39 40 00 00 li r10,0
c: 38 60 00 00 li r3,0
10: 91 49 00 00 stw r10,0(r9)
14: 4e 80 00 20 blr
And the code of my latest patch:
atomic_store_release (lock, 0);
=>aarch64-linux-gnu
0000000000000000 <pthread_spin_unlock>:
0: 889ffc1f stlr wzr, [x0]
4: 52800000 mov w0, #0x0 // #0
8: d65f03c0 ret
=>powerpc64-linux-gnu:
0000000000000000 <.pthread_spin_unlock>:
0: 7c 69 1b 78 mr r9,r3
4: 7c 20 04 ac lwsync
8: 39 40 00 00 li r10,0
c: 38 60 00 00 li r3,0
10: 91 49 00 00 stw r10,0(r9)
14: 4e 80 00 20 blr
> power consumption of a contended spin lock on armv8
> can be improved using a send-event/wait-event mechanism,
> but then the atomic_spin_nop needs to be in a loop with
> an ll/sc pair not with a relaxed load.
> (i guess we can introduce a target specific spinlock
> if this turns out to be relevant)
>
> (git apply complained about an extra newline at the
> end of atomic.h)
>
Oops. I'll fix it in the next version.
Thanks.
Stefan
More information about the Libc-alpha
mailing list