From e82ed0cd83cec1e6d15ba5a037f77c0b9f1ec8c2 Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Tue, 5 Oct 2021 14:10:39 -0700 Subject: [PATCH] runtime: start moduledata memory load early MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 --- src/runtime/symtab.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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) } -- 2.50.0