Re: master: Replace mem-reg XADD with load+add+store

Stas Boukarev <[email protected]>
Newsgroups gmane.lisp.steel-bank.cvs,gmane.lisp.steel-bank.devel
Message-ID <CAF63=13cKz-7Q+o9zvEiGE_piepYiAZg+MyyDRVooCb+af4uHA@mail.gmail.com>
Ok,  ADD QWORD PTR [R13+16], 16 is actually 3% slower than XADD. But
again, in an artificial loop.

On Sat, Aug 29, 2026 at 1:55 AM Stas Boukarev <[email protected]> wrote:
>
> or even:
> +++ b/src/compiler/x86-64/tls.lisp
> @@ -421,10 +421,9 @@ (defun binding-stack-push (node symbol index-temp
> bsp val-temp
>                             &aux (value-ea (ea 1 index-temp)))
>    (inst mov val-temp (ea index-temp thread-tn))
>    (load-binding-stack-pointer bsp)
> -  (inst add bsp (* binding-size n-word-bytes))
> -  (store-binding-stack-pointer bsp)
> -  (storew val-temp bsp (- binding-value-slot binding-size))
> -  (inst mov :dword (object-slot-ea bsp (- binding-symbol-slot
> binding-size) 0) index-temp)
> +  (inst add :qword (thread-slot-ea thread-binding-stack-pointer-slot) 16)
> +  (storew val-temp bsp binding-value-slot)
> +  (inst mov :dword (object-slot-ea bsp binding-symbol-slot 0) index-temp)
>    ;; (usually) update the indirect pointer
>    (cond ((not symbol) ; compile-time-unknown if indirection word exists
>           (assemble ()
>
> it's 1 byte shorter than xadd.
>
> On Sat, Aug 29, 2026 at 1:50 AM Stas Boukarev <[email protected]> wrote:
> >
> > What will actually break if it's:
> > ADD QWORD PTR [R13+16], 16       ; thread.binding-stack-pointer
> > MOV RDX, [R13+16]                ; thread.binding-stack-pointer
> >
> > ?
> >
> > On Sat, Aug 29, 2026 at 1:35 AM Stas Boukarev <[email protected]> wrote:
> > >
> > > It might theoretically be faster, but the latency might be eaten by
> > > something else, making shorter code a net win.
> > > Have you observed any improvements empirically?
> > >
> > > On Sat, Aug 29, 2026 at 1:31 AM snuglas via Sbcl-commits
> > > <[email protected]> wrote:
> > > >
> > > > The branch "master" has been updated in SBCL:
> > > >        via  33c68e006d3a0a30df0e6e1007743e2a9e58e6d2 (commit)
> > > >       from  db35d456122e0be7795fd50e713ce0b76a8f996d (commit)
> > > >
> > > > - Log -----------------------------------------------------------------
> > > > commit 33c68e006d3a0a30df0e6e1007743e2a9e58e6d2
> > > > Author: Douglas Katzman <[email protected]>
> > > > Date:   Fri Aug 28 17:40:59 2026 -0400
> > > >
> > > >     Replace mem-reg XADD with load+add+store
> > > >
> > > >     llvm-mca confirms that 3 instructions is better than 2 in this case.
> > > >     XADD is mainly used with :LOCK so if you don't need :LOCK, you don't need XADD
> > > > ---
> > > >  src/compiler/x86-64/tls.lisp | 18 ++++++++++--------
> > > >  1 file changed, 10 insertions(+), 8 deletions(-)
> > > >
> > > > diff --git a/src/compiler/x86-64/tls.lisp b/src/compiler/x86-64/tls.lisp
> > > > index a19717654..6824348b9 100644
> > > > --- a/src/compiler/x86-64/tls.lisp
> > > > +++ b/src/compiler/x86-64/tls.lisp
> > > > @@ -369,18 +369,19 @@
> > > >      (inst mov (thread-tls-ea tls-index) val)))
> > > >
> > > >  (defun bind (bsp symbol tmp)
> > > > -  (inst mov bsp (* binding-size n-word-bytes))
> > > > -  (inst xadd (thread-slot-ea thread-binding-stack-pointer-slot) bsp)
> > > > +  (load-binding-stack-pointer bsp)
> > > > +  (inst add bsp (* binding-size n-word-bytes))
> > > > +  (store-binding-stack-pointer bsp)
> > > >    (let* ((tls-index (load-time-tls-offset symbol))
> > > >           (tls-cell (thread-tls-ea tls-index)))
> > > >      ;; Too bad we can't use "XCHG [thread + disp], val" to write new value
> > > >      ;; and read the old value in one step. It will violate the constraints
> > > >      ;; prescribed in the internal documentation on special binding.
> > > >      (inst mov tmp tls-cell)
> > > > -    (storew tmp bsp binding-value-slot)
> > > > +    (storew tmp bsp (- binding-value-slot binding-size))
> > > >      ;; Indices are small enough to be written as :DWORDs which avoids
> > > >      ;; a REX prefix if 'bsp' happens to be any of the low 8 registers.
> > > > -    (inst mov :dword (ea (ash binding-symbol-slot word-shift) bsp) tls-index)
> > > > +    (inst mov :dword (object-slot-ea bsp (- binding-symbol-slot binding-size) 0) tls-index)
> > > >      (values tls-cell tmp)))
> > > >
> > > >  (define-vop (bind) ; bind a known symbol
> > > > @@ -419,10 +420,11 @@
> > > >                             &optional (newval nil newvalp)
> > > >                             &aux (value-ea (ea 1 index-temp)))
> > > >    (inst mov val-temp (ea index-temp thread-tn))
> > > > -  (inst mov bsp (* binding-size n-word-bytes))
> > > > -  (inst xadd (thread-slot-ea thread-binding-stack-pointer-slot) bsp)
> > > > -  (inst mov (ea (ash binding-value-slot word-shift) bsp) val-temp)
> > > > -  (inst mov :dword (ea (ash binding-symbol-slot word-shift) bsp) index-temp)
> > > > +  (load-binding-stack-pointer bsp)
> > > > +  (inst add bsp (* binding-size n-word-bytes))
> > > > +  (store-binding-stack-pointer bsp)
> > > > +  (storew val-temp bsp (- binding-value-slot binding-size))
> > > > +  (inst mov :dword (object-slot-ea bsp (- binding-symbol-slot binding-size) 0) index-temp)
> > > >    ;; (usually) update the indirect pointer
> > > >    (cond ((not symbol) ; compile-time-unknown if indirection word exists
> > > >           (assemble ()
> > > >
> > > > -----------------------------------------------------------------------
> > > >
> > > >
> > > > hooks/post-receive
> > > > --
> > > > SBCL
> > > >
> > > >
> > > > _______________________________________________
> > > > Sbcl-commits mailing list
> > > > [email protected]
> > > > https://lists.sourceforge.net/lists/listinfo/sbcl-commits


_______________________________________________
Sbcl-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/sbcl-commits
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.