1
0
mirror of https://github.com/golang/go synced 2024-11-17 15:04:45 -07:00

runtime: start moduledata memory load early

The slowest thing that can happen in funcdata is a cache miss
on moduledata.gofunc. Move that memory load earlier.

Also, for better ergonomics when working on this code,
do more calculations as uintptrs.

name                   old time/op  new time/op  delta
StackCopyWithStkobj-8  10.5ms ± 5%   9.9ms ± 4%  -6.03%  (p=0.000 n=15+15)

Change-Id: I590f4449725983c7f8d274c4ac7ed384d9018d85
Reviewed-on: https://go-review.googlesource.com/c/go/+/354134
Trust: Josh Bleecher Snyder <josharian@gmail.com>
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
This commit is contained in:
Josh Bleecher Snyder 2021-10-05 14:10:39 -07:00
parent 2a5d4ea97e
commit e82ed0cd83

View File

@ -1096,9 +1096,9 @@ func funcdata(f funcInfo, i uint8) unsafe.Pointer {
if i < 0 || i >= f.nfuncdata {
return nil
}
p := add(unsafe.Pointer(&f.nfuncdata), unsafe.Sizeof(f.nfuncdata)+uintptr(f.npcdata)*4)
p = add(p, uintptr(i)*4)
off := *(*uint32)(p)
base := f.datap.gofunc // load gofunc address early so that we calculate during cache misses
p := uintptr(unsafe.Pointer(&f.nfuncdata)) + unsafe.Sizeof(f.nfuncdata) + uintptr(f.npcdata)*4 + uintptr(i)*4
off := *(*uint32)(unsafe.Pointer(p))
// Return off == ^uint32(0) ? 0 : f.datap.gofunc + uintptr(off), but without branches.
// The compiler calculates mask on most architectures using conditional assignment.
var mask uintptr
@ -1106,7 +1106,7 @@ func funcdata(f funcInfo, i uint8) unsafe.Pointer {
mask = 1
}
mask--
raw := f.datap.gofunc + uintptr(off)
raw := base + uintptr(off)
return unsafe.Pointer(raw & mask)
}