]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: start moduledata memory load early
authorJosh Bleecher Snyder <josharian@gmail.com>
Tue, 5 Oct 2021 21:10:39 +0000 (14:10 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Tue, 5 Oct 2021 23:36:43 +0000 (23:36 +0000)
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>
src/runtime/symtab.go

index 8d21fdc42cd4d04d46c0ddd8e25df7489ad6f207..e26c05bc0c50d13bbde73cf534202ce61fa4e872 100644 (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)
 }