Commit 0e7e4368 authored by Josh Bleecher Snyder's avatar Josh Bleecher Snyder

runtime: remove a load and shift from scanobject

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: default avatarAustin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent cd285f1c
...@@ -1147,14 +1147,16 @@ func scanobject(b uintptr, gcw *gcWork) { ...@@ -1147,14 +1147,16 @@ func scanobject(b uintptr, gcw *gcWork) {
// Avoid needless hbits.next() on last iteration. // Avoid needless hbits.next() on last iteration.
hbits = hbits.next() 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 // During checkmarking, 1-word objects store the checkmark
// in the type bit for the one word. The only one-word objects // 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 // are pointers, or else they'd be merged with other non-pointer
// data into larger allocations. // 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 break // no more pointers in this object
} }
if !hbits.isPointer() { if bits&bitPointer == 0 {
continue // not a pointer continue // not a pointer
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment