]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: remove a load and shift from scanobject
authorJosh Bleecher Snyder <josharian@gmail.com>
Mon, 2 May 2016 01:02:41 +0000 (18:02 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Fri, 2 Sep 2016 19:17:43 +0000 (19:17 +0000)
hbits.morePointers and hbits.isPointer both
do a load and a shift. Do it only once.

Benchmarks using compilebench (because it is
the benchmark I have the most tooling around),
on a quiet machine.

name       old time/op      new time/op      delta
Template        291ms ±14%       290ms ±15%    ~          (p=0.702 n=100+99)
Unicode         143ms ± 9%       142ms ± 9%    ~           (p=0.126 n=99+98)
GoTypes         934ms ± 4%       933ms ± 4%    ~         (p=0.937 n=100+100)
Compiler        4.92s ± 2%       4.90s ± 1%  -0.28%        (p=0.003 n=98+98)

name       old user-ns/op   new user-ns/op   delta
Template   360user-ms ± 5%  355user-ms ± 4%  -1.37%        (p=0.000 n=97+96)
Unicode    178user-ms ± 6%  176user-ms ± 6%  -1.24%        (p=0.001 n=96+99)
GoTypes    1.22user-s ± 5%  1.21user-s ± 5%  -0.94%      (p=0.000 n=100+100)
Compiler   6.50user-s ± 2%  6.44user-s ± 3%  -0.94%        (p=0.000 n=96+98)

On amd64, before:

"".scanobject t=1 size=581 args=0x10 locals=0x78

After:

"".scanobject t=1 size=540 args=0x10 locals=0x78

Change-Id: I420ac3704549d484a5d85e19fea82c85da389514
Reviewed-on: https://go-review.googlesource.com/22712
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/runtime/mgcmark.go

index aa7f7a7769303ff83a18b2c88e97a0707cec8e97..0c624d2cbc0b69f9468b1524d42b90ee1038583a 100644 (file)
@@ -1147,14 +1147,16 @@ func scanobject(b uintptr, gcw *gcWork) {
                        // Avoid needless hbits.next() on last iteration.
                        hbits = hbits.next()
                }
+               // Load bits once. See CL 22712 and issue 16973 for discussion.
+               bits := hbits.bits()
                // During checkmarking, 1-word objects store the checkmark
                // in the type bit for the one word. The only one-word objects
                // are pointers, or else they'd be merged with other non-pointer
                // data into larger allocations.
-               if i != 1*sys.PtrSize && !hbits.morePointers() {
+               if i != 1*sys.PtrSize && bits&bitScan == 0 {
                        break // no more pointers in this object
                }
-               if !hbits.isPointer() {
+               if bits&bitPointer == 0 {
                        continue // not a pointer
                }