Skip to content

Commit a84e716

Browse files
nvanbenschotentamird
authored andcommittedDec 23, 2021
Support fast goroutine ID access on arm64
This commit updates the library to support fast access to the current goroutine ID on arm64 architectures. I noticed the need for this when running a few benchmarks in cockroachdb's `tracing` package. Unfortunately, the existing 32-bit ARM assembly does not work with arm64, because it uses a MOV instruction variant with an incorrect width (32-bit vs. 64-bit). Replacing MOVW with MOVD does the trick. See https://pkg.go.dev/cmd/internal/obj/arm64#hdr-Instructions_mnemonics_mapping_rules. I don't think CI tests on arm64, so here's some confirmation that this all works on my M1 mac: ``` ➜ go env GO111MODULE="" GOARCH="arm64" GOBIN="" GOCACHE="/Users/nathan/Library/Caches/go-build" GOENV="/Users/nathan/Library/Application Support/go/env" GOEXE="" GOEXPERIMENT="" GOFLAGS="" GOHOSTARCH="arm64" GOHOSTOS="darwin" GOINSECURE="" GOMODCACHE="/Users/nathan/Go/pkg/mod" GONOPROXY="" GONOSUMDB="" GOOS="darwin" GOPATH="/Users/nathan/Go" GOPRIVATE="" GOPROXY="https://proxy.golang.org,direct" GOROOT="/Users/nathan/Go/go" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/Users/nathan/Go/go/pkg/tool/darwin_arm64" GOVCS="" GOVERSION="go1.17.3" GCCGO="gccgo" AR="ar" CC="clang" CXX="clang++" CGO_ENABLED="1" GOMOD="/dev/null" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/hn/4tk2rm215ld9k2x8yq7rr78m0000gq/T/go-build3083548140=/tmp/go-build -gno-record-gcc-switches -fno-common" ➜ GO111MODULE=off go test . -count=1 -v === RUN TestGet --- PASS: TestGet (0.00s) PASS ok github.com/petermattis/goid 0.099s ➜ GO111MODULE=off go test . -bench=. -benchmem goos: darwin goarch: arm64 pkg: github.com/petermattis/goid BenchmarkGet-10 550983054 2.268 ns/op 0 B/op 0 allocs/op PASS ok github.com/petermattis/goid 1.583s ``` Here's the impact this change has on performance: ``` ➜ GO111MODULE=off benchdiff . checking out '7abefc4' building benchmark binaries for '7abefc4' 1/1 - checking out 'c091d1c' building benchmark binaries for 'c091d1c' 1/1 | pkg=1/1 iter=10/10 petermattis/goid \ name old time/op new time/op delta Get-10 2.21µs ± 1% 0.00µs ± 4% -99.91% (p=0.000 n=9+9) name old alloc/op new alloc/op delta Get-10 65.2B ± 2% 0.0B -100.00% (p=0.000 n=10+10) name old allocs/op new allocs/op delta Get-10 1.60 ±38% 0.00 -100.00% (p=0.000 n=10+10) ```
1 parent 8e00b2e commit a84e716

File tree

4 files changed

+35
-6
lines changed

4 files changed

+35
-6
lines changed
 

‎goid_go1.5_arm.go

+5-3
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,15 @@
1313
// permissions and limitations under the License. See the AUTHORS file
1414
// for names of contributors.
1515

16-
//go:build arm && gc && go1.5
17-
// +build arm,gc,go1.5
16+
//go:build (arm || arm64) && gc && go1.5
17+
// +build arm arm64
18+
// +build gc
19+
// +build go1.5
1820

1921
package goid
2022

2123
// Backdoor access to runtime·getg().
22-
func getg() *g // in goid_go1.5plus.s
24+
func getg() *g // in goid_go1.5_arm.s or goid_go1.5_arm64.s
2325

2426
func Get() int64 {
2527
return getg().goid

‎goid_go1.5_arm.s

-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
// for names of contributors.
1515

1616
// Assembly to mimic runtime.getg.
17-
// This should work on arm64 as well, but it hasn't been tested.
1817

1918
//go:build arm && gc && go1.5
2019
// +build arm

‎goid_go1.5_arm64.s

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright 2021 Peter Mattis.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12+
// implied. See the License for the specific language governing
13+
// permissions and limitations under the License. See the AUTHORS file
14+
// for names of contributors.
15+
16+
// Assembly to mimic runtime.getg.
17+
18+
//go:build arm64 && gc && go1.5
19+
// +build arm64
20+
// +build gc
21+
// +build go1.5
22+
23+
#include "textflag.h"
24+
25+
// func getg() *g
26+
TEXT ·getg(SB),NOSPLIT,$0-8
27+
MOVD g, ret+0(FP)
28+
RET

‎goid_slow.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
// permissions and limitations under the License. See the AUTHORS file
1414
// for names of contributors.
1515

16-
//go:build (go1.4 && !go1.5 && !amd64 && !amd64p32 && !arm && !386) || (go1.5 && !amd64 && !amd64p32 && !arm)
17-
// +build go1.4,!go1.5,!amd64,!amd64p32,!arm,!386 go1.5,!amd64,!amd64p32,!arm
16+
//go:build (go1.4 && !go1.5 && !amd64 && !amd64p32 && !arm && !386) || (go1.5 && !amd64 && !amd64p32 && !arm && !arm64)
17+
// +build go1.4,!go1.5,!amd64,!amd64p32,!arm,!386 go1.5,!amd64,!amd64p32,!arm,!arm64
1818

1919
package goid
2020

0 commit comments

Comments
 (0)
Please sign in to comment.