mirror of
https://github.com/golang/go
synced 2024-10-02 08:28:36 -06:00
runtime: implement fastrand in go
So it could be inlined. Using bit-tricks it could be implemented without condition (improved trick version by Minux Ma). Simple benchmark shows it is faster on i386 and x86_64, though I don't know will it be faster on other architectures? benchmark old ns/op new ns/op delta BenchmarkFastrand-3 2.79 1.48 -46.95% BenchmarkFastrandHashiter-3 25.9 24.9 -3.86% Change-Id: Ie2eb6d0f598c0bb5fac7f6ad0f8b5e3eddaa361b Reviewed-on: https://go-review.googlesource.com/34782 Reviewed-by: Minux Ma <minux@golang.org> Run-TryBot: Minux Ma <minux@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
9f75ecd5e1
commit
d03c124860
@ -1595,20 +1595,6 @@ allsame:
|
||||
MOVL BX, (AX)
|
||||
RET
|
||||
|
||||
TEXT runtime·fastrand(SB), NOSPLIT, $0-4
|
||||
get_tls(CX)
|
||||
MOVL g(CX), AX
|
||||
MOVL g_m(AX), AX
|
||||
MOVL m_fastrand(AX), DX
|
||||
ADDL DX, DX
|
||||
MOVL DX, BX
|
||||
XORL $0x88888eef, DX
|
||||
JPL 2(PC)
|
||||
MOVL BX, DX
|
||||
MOVL DX, m_fastrand(AX)
|
||||
MOVL DX, ret+0(FP)
|
||||
RET
|
||||
|
||||
TEXT runtime·return0(SB), NOSPLIT, $0
|
||||
MOVL $0, AX
|
||||
RET
|
||||
|
@ -2163,19 +2163,6 @@ eqret:
|
||||
MOVB $0, ret+48(FP)
|
||||
RET
|
||||
|
||||
TEXT runtime·fastrand(SB), NOSPLIT, $0-4
|
||||
get_tls(CX)
|
||||
MOVQ g(CX), AX
|
||||
MOVQ g_m(AX), AX
|
||||
MOVL m_fastrand(AX), DX
|
||||
ADDL DX, DX
|
||||
MOVL DX, BX
|
||||
XORL $0x88888eef, DX
|
||||
CMOVLMI BX, DX
|
||||
MOVL DX, m_fastrand(AX)
|
||||
MOVL DX, ret+0(FP)
|
||||
RET
|
||||
|
||||
TEXT runtime·return0(SB), NOSPLIT, $0
|
||||
MOVL $0, AX
|
||||
RET
|
||||
|
@ -991,19 +991,6 @@ eqret:
|
||||
MOVB AX, ret+24(FP)
|
||||
RET
|
||||
|
||||
TEXT runtime·fastrand(SB), NOSPLIT, $0-4
|
||||
get_tls(CX)
|
||||
MOVL g(CX), AX
|
||||
MOVL g_m(AX), AX
|
||||
MOVL m_fastrand(AX), DX
|
||||
ADDL DX, DX
|
||||
MOVL DX, BX
|
||||
XORL $0x88888eef, DX
|
||||
CMOVLMI BX, DX
|
||||
MOVL DX, m_fastrand(AX)
|
||||
MOVL DX, ret+0(FP)
|
||||
RET
|
||||
|
||||
TEXT runtime·return0(SB), NOSPLIT, $0
|
||||
MOVL $0, AX
|
||||
RET
|
||||
|
@ -971,15 +971,6 @@ _sib_notfound:
|
||||
MOVW R0, ret+12(FP)
|
||||
RET
|
||||
|
||||
TEXT runtime·fastrand(SB),NOSPLIT,$-4-4
|
||||
MOVW g_m(g), R1
|
||||
MOVW m_fastrand(R1), R0
|
||||
ADD.S R0, R0
|
||||
EOR.MI $0x88888eef, R0
|
||||
MOVW R0, m_fastrand(R1)
|
||||
MOVW R0, ret+0(FP)
|
||||
RET
|
||||
|
||||
TEXT runtime·return0(SB),NOSPLIT,$0
|
||||
MOVW $0, R0
|
||||
RET
|
||||
|
@ -959,18 +959,6 @@ equal:
|
||||
MOVB R0, ret+48(FP)
|
||||
RET
|
||||
|
||||
TEXT runtime·fastrand(SB),NOSPLIT,$-8-4
|
||||
MOVD g_m(g), R1
|
||||
MOVWU m_fastrand(R1), R0
|
||||
ADD R0, R0
|
||||
CMPW $0, R0
|
||||
BGE notneg
|
||||
EOR $0x88888eef, R0
|
||||
notneg:
|
||||
MOVW R0, m_fastrand(R1)
|
||||
MOVW R0, ret+0(FP)
|
||||
RET
|
||||
|
||||
TEXT runtime·return0(SB), NOSPLIT, $0
|
||||
MOVW $0, R0
|
||||
RET
|
||||
|
@ -831,16 +831,6 @@ notfound:
|
||||
MOVV R1, ret+24(FP)
|
||||
RET
|
||||
|
||||
TEXT runtime·fastrand(SB), NOSPLIT, $0-4
|
||||
MOVV g_m(g), R2
|
||||
MOVWU m_fastrand(R2), R1
|
||||
ADDU R1, R1
|
||||
BGEZ R1, 2(PC)
|
||||
XOR $0x88888eef, R1
|
||||
MOVW R1, m_fastrand(R2)
|
||||
MOVW R1, ret+0(FP)
|
||||
RET
|
||||
|
||||
TEXT runtime·return0(SB), NOSPLIT, $0
|
||||
MOVW $0, R1
|
||||
RET
|
||||
|
@ -904,16 +904,6 @@ cmp_ret:
|
||||
MOVW R8, ret+24(FP)
|
||||
RET
|
||||
|
||||
TEXT runtime·fastrand(SB),NOSPLIT,$0-4
|
||||
MOVW g_m(g), R2
|
||||
MOVW m_fastrand(R2), R1
|
||||
ADDU R1, R1
|
||||
BGEZ R1, 2(PC)
|
||||
XOR $0x88888eef, R1
|
||||
MOVW R1, m_fastrand(R2)
|
||||
MOVW R1, ret+0(FP)
|
||||
RET
|
||||
|
||||
TEXT runtime·return0(SB),NOSPLIT,$0
|
||||
MOVW $0, R1
|
||||
RET
|
||||
|
@ -1224,17 +1224,6 @@ TEXT bytes·Compare(SB),NOSPLIT|NOFRAME,$0-56
|
||||
BR cmpbodyBE<>(SB)
|
||||
#endif
|
||||
|
||||
TEXT runtime·fastrand(SB), NOSPLIT, $0-4
|
||||
MOVD g_m(g), R4
|
||||
MOVWZ m_fastrand(R4), R3
|
||||
ADD R3, R3
|
||||
CMPW R3, $0
|
||||
BGE 2(PC)
|
||||
XOR $0x88888eef, R3
|
||||
MOVW R3, m_fastrand(R4)
|
||||
MOVW R3, ret+0(FP)
|
||||
RET
|
||||
|
||||
TEXT runtime·return0(SB), NOSPLIT, $0
|
||||
MOVW $0, R3
|
||||
RET
|
||||
|
@ -851,17 +851,6 @@ TEXT runtime·memeqbodyclc(SB),NOSPLIT|NOFRAME,$0-0
|
||||
CLC $1, 0(R3), 0(R5)
|
||||
RET
|
||||
|
||||
TEXT runtime·fastrand(SB), NOSPLIT, $0-4
|
||||
MOVD g_m(g), R4
|
||||
MOVWZ m_fastrand(R4), R3
|
||||
ADD R3, R3
|
||||
CMPW R3, $0
|
||||
BGE 2(PC)
|
||||
XOR $0x88888eef, R3
|
||||
MOVW R3, m_fastrand(R4)
|
||||
MOVW R3, ret+0(FP)
|
||||
RET
|
||||
|
||||
TEXT bytes·IndexByte(SB),NOSPLIT|NOFRAME,$0-40
|
||||
MOVD s+0(FP), R3 // s => R3
|
||||
MOVD s_len+8(FP), R4 // s_len => R4
|
||||
|
@ -245,3 +245,5 @@ func CountPagesInUse() (pagesInUse, counted uintptr) {
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func Fastrand() uint32 { return fastrand() }
|
||||
|
32
src/runtime/rand_test.go
Normal file
32
src/runtime/rand_test.go
Normal file
@ -0,0 +1,32 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package runtime_test
|
||||
|
||||
import (
|
||||
. "runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkFastrand(b *testing.B) {
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
Fastrand()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkFastrandHashiter(b *testing.B) {
|
||||
var m = make(map[int]int, 10)
|
||||
for i := 0; i < 10; i++ {
|
||||
m[i] = i
|
||||
}
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
for _ = range m {
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
@ -93,8 +93,15 @@ func reflect_memmove(to, from unsafe.Pointer, n uintptr) {
|
||||
// exported value for testing
|
||||
var hashLoad = loadFactor
|
||||
|
||||
// in asm_*.s
|
||||
func fastrand() uint32
|
||||
//go:nosplit
|
||||
func fastrand() uint32 {
|
||||
mp := getg().m
|
||||
fr := mp.fastrand
|
||||
fr <<= 1
|
||||
fr ^= uint32(int32(fr)>>31) & 0x88888eef
|
||||
mp.fastrand = fr
|
||||
return fr
|
||||
}
|
||||
|
||||
//go:linkname sync_fastrand sync.fastrand
|
||||
func sync_fastrand() uint32 { return fastrand() }
|
||||
|
Loading…
Reference in New Issue
Block a user