mirror of
https://github.com/golang/go
synced 2024-11-19 15:44:44 -07: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)
|
MOVL BX, (AX)
|
||||||
RET
|
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
|
TEXT runtime·return0(SB), NOSPLIT, $0
|
||||||
MOVL $0, AX
|
MOVL $0, AX
|
||||||
RET
|
RET
|
||||||
|
@ -2163,19 +2163,6 @@ eqret:
|
|||||||
MOVB $0, ret+48(FP)
|
MOVB $0, ret+48(FP)
|
||||||
RET
|
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
|
TEXT runtime·return0(SB), NOSPLIT, $0
|
||||||
MOVL $0, AX
|
MOVL $0, AX
|
||||||
RET
|
RET
|
||||||
|
@ -991,19 +991,6 @@ eqret:
|
|||||||
MOVB AX, ret+24(FP)
|
MOVB AX, ret+24(FP)
|
||||||
RET
|
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
|
TEXT runtime·return0(SB), NOSPLIT, $0
|
||||||
MOVL $0, AX
|
MOVL $0, AX
|
||||||
RET
|
RET
|
||||||
|
@ -971,15 +971,6 @@ _sib_notfound:
|
|||||||
MOVW R0, ret+12(FP)
|
MOVW R0, ret+12(FP)
|
||||||
RET
|
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
|
TEXT runtime·return0(SB),NOSPLIT,$0
|
||||||
MOVW $0, R0
|
MOVW $0, R0
|
||||||
RET
|
RET
|
||||||
|
@ -959,18 +959,6 @@ equal:
|
|||||||
MOVB R0, ret+48(FP)
|
MOVB R0, ret+48(FP)
|
||||||
RET
|
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
|
TEXT runtime·return0(SB), NOSPLIT, $0
|
||||||
MOVW $0, R0
|
MOVW $0, R0
|
||||||
RET
|
RET
|
||||||
|
@ -831,16 +831,6 @@ notfound:
|
|||||||
MOVV R1, ret+24(FP)
|
MOVV R1, ret+24(FP)
|
||||||
RET
|
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
|
TEXT runtime·return0(SB), NOSPLIT, $0
|
||||||
MOVW $0, R1
|
MOVW $0, R1
|
||||||
RET
|
RET
|
||||||
|
@ -904,16 +904,6 @@ cmp_ret:
|
|||||||
MOVW R8, ret+24(FP)
|
MOVW R8, ret+24(FP)
|
||||||
RET
|
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
|
TEXT runtime·return0(SB),NOSPLIT,$0
|
||||||
MOVW $0, R1
|
MOVW $0, R1
|
||||||
RET
|
RET
|
||||||
|
@ -1224,17 +1224,6 @@ TEXT bytes·Compare(SB),NOSPLIT|NOFRAME,$0-56
|
|||||||
BR cmpbodyBE<>(SB)
|
BR cmpbodyBE<>(SB)
|
||||||
#endif
|
#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
|
TEXT runtime·return0(SB), NOSPLIT, $0
|
||||||
MOVW $0, R3
|
MOVW $0, R3
|
||||||
RET
|
RET
|
||||||
|
@ -851,17 +851,6 @@ TEXT runtime·memeqbodyclc(SB),NOSPLIT|NOFRAME,$0-0
|
|||||||
CLC $1, 0(R3), 0(R5)
|
CLC $1, 0(R3), 0(R5)
|
||||||
RET
|
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
|
TEXT bytes·IndexByte(SB),NOSPLIT|NOFRAME,$0-40
|
||||||
MOVD s+0(FP), R3 // s => R3
|
MOVD s+0(FP), R3 // s => R3
|
||||||
MOVD s_len+8(FP), R4 // s_len => R4
|
MOVD s_len+8(FP), R4 // s_len => R4
|
||||||
|
@ -245,3 +245,5 @@ func CountPagesInUse() (pagesInUse, counted uintptr) {
|
|||||||
|
|
||||||
return
|
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
|
// exported value for testing
|
||||||
var hashLoad = loadFactor
|
var hashLoad = loadFactor
|
||||||
|
|
||||||
// in asm_*.s
|
//go:nosplit
|
||||||
func fastrand() uint32
|
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
|
//go:linkname sync_fastrand sync.fastrand
|
||||||
func sync_fastrand() uint32 { return fastrand() }
|
func sync_fastrand() uint32 { return fastrand() }
|
||||||
|
Loading…
Reference in New Issue
Block a user