Skip to content

Commit 210e367

Browse files
xen0nbradfitz
authored andcommitted
runtime: use vDSO clock_gettime on linux/mips64x
Speed up nanotime1 and walltime1 on MIPS64 with vDSO, just like the other vDSO-enabled targets. Benchmark numbers on Loongson 3A3000 (GOARCH=mips64le, 1.4GHz) against current master: benchmark old ns/op new ns/op delta BenchmarkNow 868 293 -66.24% BenchmarkNowUnixNano 851 296 -65.22% Performance hit on fallback case, tested by using a wrong vDSO symbol name: benchmark old ns/op new ns/op delta BenchmarkNow 868 889 +2.42% BenchmarkNowUnixNano 851 893 +4.94% Change-Id: Ibfb48893cd060536359863ffee7624c00def646b GitHub-Last-Rev: 03a58ac GitHub-Pull-Request: #35181 Reviewed-on: https://go-review.googlesource.com/c/go/+/203578 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
1 parent bf7e55b commit 210e367

File tree

6 files changed

+106
-8
lines changed

6 files changed

+106
-8
lines changed

src/runtime/os_linux_novdso.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// license that can be found in the LICENSE file.
44

55
// +build linux
6-
// +build !386,!amd64,!arm,!arm64,!ppc64,!ppc64le
6+
// +build !386,!amd64,!arm,!arm64,!mips64,!mips64le,!ppc64,!ppc64le
77

88
package runtime
99

src/runtime/sys_linux_mips64x.s

Lines changed: 74 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -211,23 +211,88 @@ TEXT runtime·mincore(SB),NOSPLIT|NOFRAME,$0-28
211211

212212
// func walltime1() (sec int64, nsec int32)
213213
TEXT runtime·walltime1(SB),NOSPLIT,$16
214+
MOVV R29, R16 // R16 is unchanged by C code
215+
MOVV R29, R1
216+
217+
MOVV g_m(g), R17 // R17 = m
218+
219+
// Set vdsoPC and vdsoSP for SIGPROF traceback.
220+
MOVV R31, m_vdsoPC(R17)
221+
MOVV R29, m_vdsoSP(R17)
222+
223+
MOVV m_curg(R17), R4
224+
MOVV g, R5
225+
BNE R4, R5, noswitch
226+
227+
MOVV m_g0(R17), R4
228+
MOVV (g_sched+gobuf_sp)(R4), R1 // Set SP to g0 stack
229+
230+
noswitch:
231+
SUBV $16, R1
232+
AND $~15, R1 // Align for C code
233+
MOVV R1, R29
234+
214235
MOVW $0, R4 // CLOCK_REALTIME
215236
MOVV $0(R29), R5
216-
MOVV $SYS_clock_gettime, R2
217-
SYSCALL
237+
238+
MOVV runtime·vdsoClockgettimeSym(SB), R25
239+
BEQ R25, fallback
240+
241+
JAL (R25)
242+
243+
finish:
218244
MOVV 0(R29), R3 // sec
219245
MOVV 8(R29), R5 // nsec
246+
247+
MOVV R16, R29 // restore SP
248+
MOVV R0, m_vdsoSP(R17) // clear vdsoSP
249+
220250
MOVV R3, sec+0(FP)
221251
MOVW R5, nsec+8(FP)
222252
RET
223253

254+
fallback:
255+
MOVV $SYS_clock_gettime, R2
256+
SYSCALL
257+
JMP finish
258+
224259
TEXT runtime·nanotime1(SB),NOSPLIT,$16
260+
MOVV R29, R16 // R16 is unchanged by C code
261+
MOVV R29, R1
262+
263+
MOVV g_m(g), R17 // R17 = m
264+
265+
// Set vdsoPC and vdsoSP for SIGPROF traceback.
266+
MOVV R31, m_vdsoPC(R17)
267+
MOVV R29, m_vdsoSP(R17)
268+
269+
MOVV m_curg(R17), R4
270+
MOVV g, R5
271+
BNE R4, R5, noswitch
272+
273+
MOVV m_g0(R17), R4
274+
MOVV (g_sched+gobuf_sp)(R4), R1 // Set SP to g0 stack
275+
276+
noswitch:
277+
SUBV $16, R1
278+
AND $~15, R1 // Align for C code
279+
MOVV R1, R29
280+
225281
MOVW $1, R4 // CLOCK_MONOTONIC
226282
MOVV $0(R29), R5
227-
MOVV $SYS_clock_gettime, R2
228-
SYSCALL
283+
284+
MOVV runtime·vdsoClockgettimeSym(SB), R25
285+
BEQ R25, fallback
286+
287+
JAL (R25)
288+
289+
finish:
229290
MOVV 0(R29), R3 // sec
230291
MOVV 8(R29), R5 // nsec
292+
293+
MOVV R16, R29 // restore SP
294+
MOVV R0, m_vdsoSP(R17) // clear vdsoSP
295+
231296
// sec is in R3, nsec in R5
232297
// return nsec in R3
233298
MOVV $1000000000, R4
@@ -237,6 +302,11 @@ TEXT runtime·nanotime1(SB),NOSPLIT,$16
237302
MOVV R3, ret+0(FP)
238303
RET
239304

305+
fallback:
306+
MOVV $SYS_clock_gettime, R2
307+
SYSCALL
308+
JMP finish
309+
240310
TEXT runtime·rtsigprocmask(SB),NOSPLIT|NOFRAME,$0-28
241311
MOVW how+0(FP), R4
242312
MOVV new+8(FP), R5

src/runtime/vdso_elf64.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// license that can be found in the LICENSE file.
44

55
// +build linux
6-
// +build amd64 arm64 ppc64 ppc64le
6+
// +build amd64 arm64 mips64 mips64le ppc64 ppc64le
77

88
package runtime
99

src/runtime/vdso_in_none.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5-
// +build linux,!386,!amd64,!arm,!arm64,!ppc64,!ppc64le !linux
5+
// +build linux,!386,!amd64,!arm,!arm64,!mips64,!mips64le,!ppc64,!ppc64le !linux
66

77
package runtime
88

src/runtime/vdso_linux.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// license that can be found in the LICENSE file.
44

55
// +build linux
6-
// +build 386 amd64 arm arm64 ppc64 ppc64le
6+
// +build 386 amd64 arm arm64 mips64 mips64le ppc64 ppc64le
77

88
package runtime
99

src/runtime/vdso_linux_mips64x.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright 2019 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
// +build linux
6+
// +build mips64 mips64le
7+
8+
package runtime
9+
10+
const (
11+
// vdsoArrayMax is the byte-size of a maximally sized array on this architecture.
12+
// See cmd/compile/internal/mips64/galign.go arch.MAXWIDTH initialization.
13+
vdsoArrayMax = 1<<50 - 1
14+
)
15+
16+
// see man 7 vdso : mips
17+
var vdsoLinuxVersion = vdsoVersionKey{"LINUX_2.6", 0x3ae75f6}
18+
19+
// The symbol name is not __kernel_clock_gettime as suggested by the manpage;
20+
// according to Linux source code it should be __vdso_clock_gettime instead.
21+
var vdsoSymbolKeys = []vdsoSymbolKey{
22+
{"__vdso_clock_gettime", 0xd35ec75, 0x6e43a318, &vdsoClockgettimeSym},
23+
}
24+
25+
// initialize to fall back to syscall
26+
var (
27+
vdsoClockgettimeSym uintptr = 0
28+
)

0 commit comments

Comments
 (0)