]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: add a benchmark of FPCallers
authorFelix Geisendörfer <felix.geisendoerfer@datadoghq.com>
Mon, 13 Mar 2023 08:56:45 +0000 (09:56 +0100)
committerMichael Pratt <mpratt@google.com>
Thu, 30 Mar 2023 19:18:18 +0000 (19:18 +0000)
This allows comparing frame pointer unwinding against the default
unwinder as shown below.

goos: linux
goarch: amd64
pkg: runtime
cpu: Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz
                    │ callers.txt │
                    │   sec/op    │
Callers/cached-32     1.254µ ± 0%
FPCallers/cached-32   24.99n ± 0%

For #16638

Change-Id: I4dd05f82254726152ef4a5d5beceab33641e9d2b
Reviewed-on: https://go-review.googlesource.com/c/go/+/475795
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Felix Geisendörfer <felix.geisendoerfer@datadoghq.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
src/runtime/callers_test.go
src/runtime/export_test.go

index d738076a2fecadba71baf819c4c1a8fd15400eb9..e52357f175c2cb0abe9b61e8f403c23c70d77bc4 100644 (file)
@@ -430,3 +430,23 @@ func callersNoCache(b *testing.B, n int) int {
                return 1 + callersNoCache(b, n-1)
        }
 }
+
+func BenchmarkFPCallers(b *testing.B) {
+       b.Run("cached", func(b *testing.B) {
+               // Very pcvalueCache-friendly, no inlining.
+               fpCallersCached(b, 100)
+       })
+}
+
+func fpCallersCached(b *testing.B, n int) int {
+       if n <= 0 {
+               pcs := make([]uintptr, 32)
+               b.ResetTimer()
+               for i := 0; i < b.N; i++ {
+                       runtime.FPCallers(0, pcs)
+               }
+               b.StopTimer()
+               return 0
+       }
+       return 1 + fpCallersCached(b, n-1)
+}
index 367362b6721779c6dd642206185a61bc8dc5b333..498c63f5b65dae9c94127cf0f044d8ef301917e7 100644 (file)
@@ -1727,3 +1727,9 @@ func FrameStartLine(f *Frame) int {
 func PersistentAlloc(n uintptr) unsafe.Pointer {
        return persistentalloc(n, 0, &memstats.other_sys)
 }
+
+// FPCallers works like Callers and uses frame pointer unwinding to populate
+// pcBuf with the return addresses of the physical frames on the stack.
+func FPCallers(skip int, pcBuf []uintptr) int {
+       return fpTracebackPCs(unsafe.Pointer(getcallerfp()), skip, pcBuf)
+}