Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Improve Interlocked.Exchange<T> #16058

Merged
merged 1 commit into from
Jan 28, 2018
Merged

Improve Interlocked.Exchange<T> #16058

merged 1 commit into from
Jan 28, 2018

Conversation

mikedn
Copy link

@mikedn mikedn commented Jan 28, 2018

Replace TypedReference with Unsafe.As, it generates far less code and, with the help of AggresiveInlining, it allows Exchange<T> to inline.

Fixes #16051

@mikedn
Copy link
Author

mikedn commented Jan 28, 2018

The TypedReference based Exchange<T> generated

G_M49272_IG01:
       push     rdi
       push     rsi
       sub      rsp, 72
       mov      rsi, rcx
       lea      rdi, [rsp+20H]
       mov      ecx, 8
       xor      rax, rax
       rep stosd 
       mov      rcx, rsi
       mov      qword ptr [rsp+40H], rcx
       mov      gword ptr [rsp+70H], r8
G_M49272_IG02:
       mov      rcx, qword ptr [rcx+16]
       mov      rcx, qword ptr [rcx]
       mov      rax, rcx
       mov      r8d, eax
       and      r8d, 1
       test     r8d, r8d
       je       SHORT G_M49272_IG03
       mov      rax, qword ptr [rax-1]
G_M49272_IG03:
       test     r8d, r8d
       je       SHORT G_M49272_IG04
       mov      rcx, qword ptr [rcx-1]
G_M49272_IG04:
       mov      qword ptr [rsp+30H], rdx
       mov      qword ptr [rsp+38H], rax
       lea      rdx, bword ptr [rsp+70H]
       mov      qword ptr [rsp+20H], rdx
       mov      qword ptr [rsp+28H], rcx
       lea      rcx, bword ptr [rsp+30H]
       lea      rdx, bword ptr [rsp+20H]
       call     Interlocked:_Exchange(struct,struct)
       mov      rax, gword ptr [rsp+70H]
G_M49272_IG05:
       add      rsp, 72
       pop      rsi
       pop      rdi
       ret      
; Total bytes of code 123, prolog size 31 for method Interlocked:Exchange(byref,ref):ref

No wonder it was slower.

@jkotas
Copy link
Member

jkotas commented Jan 28, 2018

Could you please also delete the TypedReference-based _Exchange ?

Replace TypedReference with Unsafe.As, it generates far less code and, with the help of AggresiveInlining, it allows Exchange<T> to inline.
@mikedn
Copy link
Author

mikedn commented Jan 28, 2018

Deleted TypedReference overloads.

@mikedn
Copy link
Author

mikedn commented Jan 28, 2018

Now both Exchange<T> and CompareExchange<T> generate similar code, they both end up calling the object overload:

       488BCE               mov      rcx, rsi
       33D2                 xor      rdx, rdx
       E8BE174E5F           call     System.Threading.Interlocked:Exchange(byref,ref):ref
       488BCE               mov      rcx, rsi
       33D2                 xor      rdx, rdx
       4533C0               xor      r8, r8
       E8E1044E5F           call     System.Threading.Interlocked:CompareExchange(byref,ref,ref):ref

Copy link
Member

@jkotas jkotas left a comment

Choose a reason for hiding this comment

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

Thank you!

@jkotas
Copy link
Member

jkotas commented Jan 28, 2018

@dotnet-bot test Ubuntu x64 Checked Innerloop Build and Test please

@jkotas jkotas merged commit e3562c9 into dotnet:master Jan 28, 2018
@mikedn mikedn deleted the inter-exch branch March 25, 2018 10:40
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants