From: Josh Bleecher Snyder Date: Tue, 5 Oct 2021 21:10:39 +0000 (-0700) Subject: runtime: start moduledata memory load early X-Git-Tag: go1.18beta1~1030 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=e82ed0cd83cec1e6d15ba5a037f77c0b9f1ec8c2;p=gostls13.git 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 Run-TryBot: Josh Bleecher Snyder TryBot-Result: Go Bot Reviewed-by: Cherry Mui --- diff --git a/src/runtime/symtab.go b/src/runtime/symtab.go index 8d21fdc42c..e26c05bc0c 100644 --- a/src/runtime/symtab.go +++ b/src/runtime/symtab.go @@ -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) }