mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime: faster memclr on x86.
Use explicit SSE writes instead of REP STOSQ. benchmark old ns/op new ns/op delta BenchmarkMemclr5 22 5 -73.62% BenchmarkMemclr16 27 5 -78.49% BenchmarkMemclr64 28 6 -76.43% BenchmarkMemclr256 34 8 -74.94% BenchmarkMemclr4096 112 84 -24.73% BenchmarkMemclr65536 1902 1920 +0.95% LGTM=dvyukov R=golang-codereviews, dvyukov CC=golang-codereviews https://golang.org/cl/60090044
This commit is contained in:
parent
aac872e118
commit
da7cf0ba5d
11 changed files with 324 additions and 62 deletions
|
|
@ -781,6 +781,7 @@ struct
|
||||||
"PSUBW", LTYPE3, APSUBW,
|
"PSUBW", LTYPE3, APSUBW,
|
||||||
"PUNPCKHQDQ", LTYPE3, APUNPCKHQDQ,
|
"PUNPCKHQDQ", LTYPE3, APUNPCKHQDQ,
|
||||||
"PUNPCKLQDQ", LTYPE3, APUNPCKLQDQ,
|
"PUNPCKLQDQ", LTYPE3, APUNPCKLQDQ,
|
||||||
|
"PXOR", LTYPE3, APXOR,
|
||||||
"RCPPS", LTYPE3, ARCPPS,
|
"RCPPS", LTYPE3, ARCPPS,
|
||||||
"RCPSS", LTYPE3, ARCPSS,
|
"RCPSS", LTYPE3, ARCPSS,
|
||||||
"RSQRTPS", LTYPE3, ARSQRTPS,
|
"RSQRTPS", LTYPE3, ARSQRTPS,
|
||||||
|
|
|
||||||
|
|
@ -547,6 +547,7 @@ enum as
|
||||||
APSUBW,
|
APSUBW,
|
||||||
APUNPCKHQDQ,
|
APUNPCKHQDQ,
|
||||||
APUNPCKLQDQ,
|
APUNPCKLQDQ,
|
||||||
|
APXOR,
|
||||||
ARCPPS,
|
ARCPPS,
|
||||||
ARCPSS,
|
ARCPSS,
|
||||||
ARSQRTPS,
|
ARSQRTPS,
|
||||||
|
|
|
||||||
|
|
@ -1115,6 +1115,7 @@ static Optab optab[] =
|
||||||
{ APSUBW, yxm, Pe, 0xf9 },
|
{ APSUBW, yxm, Pe, 0xf9 },
|
||||||
{ APUNPCKHQDQ, yxm, Pe, 0x6d },
|
{ APUNPCKHQDQ, yxm, Pe, 0x6d },
|
||||||
{ APUNPCKLQDQ, yxm, Pe, 0x6c },
|
{ APUNPCKLQDQ, yxm, Pe, 0x6c },
|
||||||
|
{ APXOR, yxm, Pe, 0xef },
|
||||||
{ ARCPPS, yxm, Pm, 0x53 },
|
{ ARCPPS, yxm, Pm, 0x53 },
|
||||||
{ ARCPSS, yxm, Pf3, 0x53 },
|
{ ARCPSS, yxm, Pf3, 0x53 },
|
||||||
{ ARSQRTPS, yxm, Pm, 0x52 },
|
{ ARSQRTPS, yxm, Pm, 0x52 },
|
||||||
|
|
|
||||||
|
|
@ -514,6 +514,11 @@ runtime·equal(Type *t, ...)
|
||||||
t->alg->equal((bool*)ret, t->size, x, y);
|
t->alg->equal((bool*)ret, t->size, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Testing adapter for memclr
|
||||||
|
void runtime·memclrBytes(Slice s) {
|
||||||
|
runtime·memclr(s.array, s.len);
|
||||||
|
}
|
||||||
|
|
||||||
// Testing adapters for hash quality tests (see hash_test.go)
|
// Testing adapters for hash quality tests (see hash_test.go)
|
||||||
void runtime·haveGoodHash(bool res) {
|
void runtime·haveGoodHash(bool res) {
|
||||||
res = use_aeshash;
|
res = use_aeshash;
|
||||||
|
|
|
||||||
|
|
@ -753,21 +753,6 @@ TEXT runtime·stackcheck(SB), NOSPLIT, $0-0
|
||||||
INT $3
|
INT $3
|
||||||
RET
|
RET
|
||||||
|
|
||||||
TEXT runtime·memclr(SB),NOSPLIT,$0-8
|
|
||||||
MOVL 4(SP), DI // arg 1 addr
|
|
||||||
MOVL 8(SP), CX // arg 2 count
|
|
||||||
MOVL CX, BX
|
|
||||||
ANDL $3, BX
|
|
||||||
SHRL $2, CX
|
|
||||||
MOVL $0, AX
|
|
||||||
CLD
|
|
||||||
REP
|
|
||||||
STOSL
|
|
||||||
MOVL BX, CX
|
|
||||||
REP
|
|
||||||
STOSB
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT runtime·getcallerpc(SB),NOSPLIT,$0-4
|
TEXT runtime·getcallerpc(SB),NOSPLIT,$0-4
|
||||||
MOVL x+0(FP),AX // addr of first arg
|
MOVL x+0(FP),AX // addr of first arg
|
||||||
MOVL -4(AX),AX // get calling pc
|
MOVL -4(AX),AX // get calling pc
|
||||||
|
|
|
||||||
|
|
@ -794,21 +794,6 @@ TEXT runtime·stackcheck(SB), NOSPLIT, $0-0
|
||||||
INT $3
|
INT $3
|
||||||
RET
|
RET
|
||||||
|
|
||||||
TEXT runtime·memclr(SB),NOSPLIT,$0-16
|
|
||||||
MOVQ 8(SP), DI // arg 1 addr
|
|
||||||
MOVQ 16(SP), CX // arg 2 count
|
|
||||||
MOVQ CX, BX
|
|
||||||
ANDQ $7, BX
|
|
||||||
SHRQ $3, CX
|
|
||||||
MOVQ $0, AX
|
|
||||||
CLD
|
|
||||||
REP
|
|
||||||
STOSQ
|
|
||||||
MOVQ BX, CX
|
|
||||||
REP
|
|
||||||
STOSB
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT runtime·getcallerpc(SB),NOSPLIT,$0-8
|
TEXT runtime·getcallerpc(SB),NOSPLIT,$0-8
|
||||||
MOVQ x+0(FP),AX // addr of first arg
|
MOVQ x+0(FP),AX // addr of first arg
|
||||||
MOVQ -8(AX),AX // get calling pc
|
MOVQ -8(AX),AX // get calling pc
|
||||||
|
|
|
||||||
|
|
@ -84,3 +84,7 @@ func GogoBytes() int32
|
||||||
|
|
||||||
var hashLoad float64 // declared in hashmap.c
|
var hashLoad float64 // declared in hashmap.c
|
||||||
var HashLoad = &hashLoad
|
var HashLoad = &hashLoad
|
||||||
|
|
||||||
|
func memclrBytes(b []byte)
|
||||||
|
|
||||||
|
var MemclrBytes = memclrBytes
|
||||||
|
|
|
||||||
125
src/pkg/runtime/memclr_386.s
Normal file
125
src/pkg/runtime/memclr_386.s
Normal file
|
|
@ -0,0 +1,125 @@
|
||||||
|
// Copyright 2014 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.
|
||||||
|
|
||||||
|
#include "../../cmd/ld/textflag.h"
|
||||||
|
|
||||||
|
// void runtime·memclr(void*, uintptr)
|
||||||
|
TEXT runtime·memclr(SB), NOSPLIT, $0-8
|
||||||
|
MOVL ptr+0(FP), DI
|
||||||
|
MOVL n+4(FP), BX
|
||||||
|
XORL AX, AX
|
||||||
|
|
||||||
|
// MOVOU seems always faster than REP STOSL.
|
||||||
|
clr_tail:
|
||||||
|
TESTL BX, BX
|
||||||
|
JEQ clr_0
|
||||||
|
CMPL BX, $2
|
||||||
|
JBE clr_1or2
|
||||||
|
CMPL BX, $4
|
||||||
|
JBE clr_3or4
|
||||||
|
CMPL BX, $8
|
||||||
|
JBE clr_5through8
|
||||||
|
CMPL BX, $16
|
||||||
|
JBE clr_9through16
|
||||||
|
TESTL $0x4000000, runtime·cpuid_edx(SB) // check for sse2
|
||||||
|
JEQ nosse2
|
||||||
|
PXOR X0, X0
|
||||||
|
CMPL BX, $32
|
||||||
|
JBE clr_17through32
|
||||||
|
CMPL BX, $64
|
||||||
|
JBE clr_33through64
|
||||||
|
CMPL BX, $128
|
||||||
|
JBE clr_65through128
|
||||||
|
CMPL BX, $256
|
||||||
|
JBE clr_129through256
|
||||||
|
// TODO: use branch table and BSR to make this just a single dispatch
|
||||||
|
|
||||||
|
clr_loop:
|
||||||
|
MOVOU X0, 0(DI)
|
||||||
|
MOVOU X0, 16(DI)
|
||||||
|
MOVOU X0, 32(DI)
|
||||||
|
MOVOU X0, 48(DI)
|
||||||
|
MOVOU X0, 64(DI)
|
||||||
|
MOVOU X0, 80(DI)
|
||||||
|
MOVOU X0, 96(DI)
|
||||||
|
MOVOU X0, 112(DI)
|
||||||
|
MOVOU X0, 128(DI)
|
||||||
|
MOVOU X0, 144(DI)
|
||||||
|
MOVOU X0, 160(DI)
|
||||||
|
MOVOU X0, 176(DI)
|
||||||
|
MOVOU X0, 192(DI)
|
||||||
|
MOVOU X0, 208(DI)
|
||||||
|
MOVOU X0, 224(DI)
|
||||||
|
MOVOU X0, 240(DI)
|
||||||
|
SUBL $256, BX
|
||||||
|
ADDL $256, DI
|
||||||
|
CMPL BX, $256
|
||||||
|
JAE clr_loop
|
||||||
|
JMP clr_tail
|
||||||
|
|
||||||
|
clr_1or2:
|
||||||
|
MOVB AX, (DI)
|
||||||
|
MOVB AX, -1(DI)(BX*1)
|
||||||
|
clr_0:
|
||||||
|
RET
|
||||||
|
clr_3or4:
|
||||||
|
MOVW AX, (DI)
|
||||||
|
MOVW AX, -2(DI)(BX*1)
|
||||||
|
RET
|
||||||
|
clr_5through8:
|
||||||
|
MOVL AX, (DI)
|
||||||
|
MOVL AX, -4(DI)(BX*1)
|
||||||
|
RET
|
||||||
|
clr_9through16:
|
||||||
|
MOVL AX, (DI)
|
||||||
|
MOVL AX, 4(DI)
|
||||||
|
MOVL AX, -8(DI)(BX*1)
|
||||||
|
MOVL AX, -4(DI)(BX*1)
|
||||||
|
RET
|
||||||
|
clr_17through32:
|
||||||
|
MOVOU X0, (DI)
|
||||||
|
MOVOU X0, -16(DI)(BX*1)
|
||||||
|
RET
|
||||||
|
clr_33through64:
|
||||||
|
MOVOU X0, (DI)
|
||||||
|
MOVOU X0, 16(DI)
|
||||||
|
MOVOU X0, -32(DI)(BX*1)
|
||||||
|
MOVOU X0, -16(DI)(BX*1)
|
||||||
|
RET
|
||||||
|
clr_65through128:
|
||||||
|
MOVOU X0, (DI)
|
||||||
|
MOVOU X0, 16(DI)
|
||||||
|
MOVOU X0, 32(DI)
|
||||||
|
MOVOU X0, 48(DI)
|
||||||
|
MOVOU X0, -64(DI)(BX*1)
|
||||||
|
MOVOU X0, -48(DI)(BX*1)
|
||||||
|
MOVOU X0, -32(DI)(BX*1)
|
||||||
|
MOVOU X0, -16(DI)(BX*1)
|
||||||
|
RET
|
||||||
|
clr_129through256:
|
||||||
|
MOVOU X0, (DI)
|
||||||
|
MOVOU X0, 16(DI)
|
||||||
|
MOVOU X0, 32(DI)
|
||||||
|
MOVOU X0, 48(DI)
|
||||||
|
MOVOU X0, 64(DI)
|
||||||
|
MOVOU X0, 80(DI)
|
||||||
|
MOVOU X0, 96(DI)
|
||||||
|
MOVOU X0, 112(DI)
|
||||||
|
MOVOU X0, -128(DI)(BX*1)
|
||||||
|
MOVOU X0, -112(DI)(BX*1)
|
||||||
|
MOVOU X0, -96(DI)(BX*1)
|
||||||
|
MOVOU X0, -80(DI)(BX*1)
|
||||||
|
MOVOU X0, -64(DI)(BX*1)
|
||||||
|
MOVOU X0, -48(DI)(BX*1)
|
||||||
|
MOVOU X0, -32(DI)(BX*1)
|
||||||
|
MOVOU X0, -16(DI)(BX*1)
|
||||||
|
RET
|
||||||
|
nosse2:
|
||||||
|
MOVL BX, CX
|
||||||
|
SHRL $2, CX
|
||||||
|
REP
|
||||||
|
STOSL
|
||||||
|
ANDL $3, BX
|
||||||
|
JNE clr_tail
|
||||||
|
RET
|
||||||
114
src/pkg/runtime/memclr_amd64.s
Normal file
114
src/pkg/runtime/memclr_amd64.s
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
// Copyright 2014 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.
|
||||||
|
|
||||||
|
#include "../../cmd/ld/textflag.h"
|
||||||
|
|
||||||
|
// void runtime·memclr(void*, uintptr)
|
||||||
|
TEXT runtime·memclr(SB), NOSPLIT, $0-16
|
||||||
|
MOVQ ptr+0(FP), DI
|
||||||
|
MOVQ n+8(FP), BX
|
||||||
|
XORQ AX, AX
|
||||||
|
|
||||||
|
// MOVOU seems always faster than REP STOSQ.
|
||||||
|
clr_tail:
|
||||||
|
TESTQ BX, BX
|
||||||
|
JEQ clr_0
|
||||||
|
CMPQ BX, $2
|
||||||
|
JBE clr_1or2
|
||||||
|
CMPQ BX, $4
|
||||||
|
JBE clr_3or4
|
||||||
|
CMPQ BX, $8
|
||||||
|
JBE clr_5through8
|
||||||
|
CMPQ BX, $16
|
||||||
|
JBE clr_9through16
|
||||||
|
PXOR X0, X0
|
||||||
|
CMPQ BX, $32
|
||||||
|
JBE clr_17through32
|
||||||
|
CMPQ BX, $64
|
||||||
|
JBE clr_33through64
|
||||||
|
CMPQ BX, $128
|
||||||
|
JBE clr_65through128
|
||||||
|
CMPQ BX, $256
|
||||||
|
JBE clr_129through256
|
||||||
|
// TODO: use branch table and BSR to make this just a single dispatch
|
||||||
|
// TODO: for really big clears, use MOVNTDQ.
|
||||||
|
|
||||||
|
clr_loop:
|
||||||
|
MOVOU X0, 0(DI)
|
||||||
|
MOVOU X0, 16(DI)
|
||||||
|
MOVOU X0, 32(DI)
|
||||||
|
MOVOU X0, 48(DI)
|
||||||
|
MOVOU X0, 64(DI)
|
||||||
|
MOVOU X0, 80(DI)
|
||||||
|
MOVOU X0, 96(DI)
|
||||||
|
MOVOU X0, 112(DI)
|
||||||
|
MOVOU X0, 128(DI)
|
||||||
|
MOVOU X0, 144(DI)
|
||||||
|
MOVOU X0, 160(DI)
|
||||||
|
MOVOU X0, 176(DI)
|
||||||
|
MOVOU X0, 192(DI)
|
||||||
|
MOVOU X0, 208(DI)
|
||||||
|
MOVOU X0, 224(DI)
|
||||||
|
MOVOU X0, 240(DI)
|
||||||
|
SUBQ $256, BX
|
||||||
|
ADDQ $256, DI
|
||||||
|
CMPQ BX, $256
|
||||||
|
JAE clr_loop
|
||||||
|
JMP clr_tail
|
||||||
|
|
||||||
|
clr_1or2:
|
||||||
|
MOVB AX, (DI)
|
||||||
|
MOVB AX, -1(DI)(BX*1)
|
||||||
|
clr_0:
|
||||||
|
RET
|
||||||
|
clr_3or4:
|
||||||
|
MOVW AX, (DI)
|
||||||
|
MOVW AX, -2(DI)(BX*1)
|
||||||
|
RET
|
||||||
|
clr_5through8:
|
||||||
|
MOVL AX, (DI)
|
||||||
|
MOVL AX, -4(DI)(BX*1)
|
||||||
|
RET
|
||||||
|
clr_9through16:
|
||||||
|
MOVQ AX, (DI)
|
||||||
|
MOVQ AX, -8(DI)(BX*1)
|
||||||
|
RET
|
||||||
|
clr_17through32:
|
||||||
|
MOVOU X0, (DI)
|
||||||
|
MOVOU X0, -16(DI)(BX*1)
|
||||||
|
RET
|
||||||
|
clr_33through64:
|
||||||
|
MOVOU X0, (DI)
|
||||||
|
MOVOU X0, 16(DI)
|
||||||
|
MOVOU X0, -32(DI)(BX*1)
|
||||||
|
MOVOU X0, -16(DI)(BX*1)
|
||||||
|
RET
|
||||||
|
clr_65through128:
|
||||||
|
MOVOU X0, (DI)
|
||||||
|
MOVOU X0, 16(DI)
|
||||||
|
MOVOU X0, 32(DI)
|
||||||
|
MOVOU X0, 48(DI)
|
||||||
|
MOVOU X0, -64(DI)(BX*1)
|
||||||
|
MOVOU X0, -48(DI)(BX*1)
|
||||||
|
MOVOU X0, -32(DI)(BX*1)
|
||||||
|
MOVOU X0, -16(DI)(BX*1)
|
||||||
|
RET
|
||||||
|
clr_129through256:
|
||||||
|
MOVOU X0, (DI)
|
||||||
|
MOVOU X0, 16(DI)
|
||||||
|
MOVOU X0, 32(DI)
|
||||||
|
MOVOU X0, 48(DI)
|
||||||
|
MOVOU X0, 64(DI)
|
||||||
|
MOVOU X0, 80(DI)
|
||||||
|
MOVOU X0, 96(DI)
|
||||||
|
MOVOU X0, 112(DI)
|
||||||
|
MOVOU X0, -128(DI)(BX*1)
|
||||||
|
MOVOU X0, -112(DI)(BX*1)
|
||||||
|
MOVOU X0, -96(DI)(BX*1)
|
||||||
|
MOVOU X0, -80(DI)(BX*1)
|
||||||
|
MOVOU X0, -64(DI)(BX*1)
|
||||||
|
MOVOU X0, -48(DI)(BX*1)
|
||||||
|
MOVOU X0, -32(DI)(BX*1)
|
||||||
|
MOVOU X0, -16(DI)(BX*1)
|
||||||
|
RET
|
||||||
|
|
@ -40,12 +40,6 @@ TEXT runtime·memclr(SB),NOSPLIT,$0-8
|
||||||
CMP $4, R(N) /* need at least 4 bytes to copy */
|
CMP $4, R(N) /* need at least 4 bytes to copy */
|
||||||
BLT _1tail
|
BLT _1tail
|
||||||
|
|
||||||
AND $0xFF, R(0) /* it's a byte */
|
|
||||||
SLL $8, R(0), R(TMP) /* replicate to a word */
|
|
||||||
ORR R(TMP), R(0)
|
|
||||||
SLL $16, R(0), R(TMP)
|
|
||||||
ORR R(TMP), R(0)
|
|
||||||
|
|
||||||
_4align: /* align on 4 */
|
_4align: /* align on 4 */
|
||||||
AND.S $3, R(TO), R(TMP)
|
AND.S $3, R(TO), R(TMP)
|
||||||
BEQ _4aligned
|
BEQ _4aligned
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
package runtime_test
|
package runtime_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
. "runtime"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -80,7 +81,7 @@ func TestMemmoveAlias(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func bmMemmove(n int, b *testing.B) {
|
func bmMemmove(b *testing.B, n int) {
|
||||||
x := make([]byte, n)
|
x := make([]byte, n)
|
||||||
y := make([]byte, n)
|
y := make([]byte, n)
|
||||||
b.SetBytes(int64(n))
|
b.SetBytes(int64(n))
|
||||||
|
|
@ -89,28 +90,74 @@ func bmMemmove(n int, b *testing.B) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkMemmove0(b *testing.B) { bmMemmove(0, b) }
|
func BenchmarkMemmove0(b *testing.B) { bmMemmove(b, 0) }
|
||||||
func BenchmarkMemmove1(b *testing.B) { bmMemmove(1, b) }
|
func BenchmarkMemmove1(b *testing.B) { bmMemmove(b, 1) }
|
||||||
func BenchmarkMemmove2(b *testing.B) { bmMemmove(2, b) }
|
func BenchmarkMemmove2(b *testing.B) { bmMemmove(b, 2) }
|
||||||
func BenchmarkMemmove3(b *testing.B) { bmMemmove(3, b) }
|
func BenchmarkMemmove3(b *testing.B) { bmMemmove(b, 3) }
|
||||||
func BenchmarkMemmove4(b *testing.B) { bmMemmove(4, b) }
|
func BenchmarkMemmove4(b *testing.B) { bmMemmove(b, 4) }
|
||||||
func BenchmarkMemmove5(b *testing.B) { bmMemmove(5, b) }
|
func BenchmarkMemmove5(b *testing.B) { bmMemmove(b, 5) }
|
||||||
func BenchmarkMemmove6(b *testing.B) { bmMemmove(6, b) }
|
func BenchmarkMemmove6(b *testing.B) { bmMemmove(b, 6) }
|
||||||
func BenchmarkMemmove7(b *testing.B) { bmMemmove(7, b) }
|
func BenchmarkMemmove7(b *testing.B) { bmMemmove(b, 7) }
|
||||||
func BenchmarkMemmove8(b *testing.B) { bmMemmove(8, b) }
|
func BenchmarkMemmove8(b *testing.B) { bmMemmove(b, 8) }
|
||||||
func BenchmarkMemmove9(b *testing.B) { bmMemmove(9, b) }
|
func BenchmarkMemmove9(b *testing.B) { bmMemmove(b, 9) }
|
||||||
func BenchmarkMemmove10(b *testing.B) { bmMemmove(10, b) }
|
func BenchmarkMemmove10(b *testing.B) { bmMemmove(b, 10) }
|
||||||
func BenchmarkMemmove11(b *testing.B) { bmMemmove(11, b) }
|
func BenchmarkMemmove11(b *testing.B) { bmMemmove(b, 11) }
|
||||||
func BenchmarkMemmove12(b *testing.B) { bmMemmove(12, b) }
|
func BenchmarkMemmove12(b *testing.B) { bmMemmove(b, 12) }
|
||||||
func BenchmarkMemmove13(b *testing.B) { bmMemmove(13, b) }
|
func BenchmarkMemmove13(b *testing.B) { bmMemmove(b, 13) }
|
||||||
func BenchmarkMemmove14(b *testing.B) { bmMemmove(14, b) }
|
func BenchmarkMemmove14(b *testing.B) { bmMemmove(b, 14) }
|
||||||
func BenchmarkMemmove15(b *testing.B) { bmMemmove(15, b) }
|
func BenchmarkMemmove15(b *testing.B) { bmMemmove(b, 15) }
|
||||||
func BenchmarkMemmove16(b *testing.B) { bmMemmove(16, b) }
|
func BenchmarkMemmove16(b *testing.B) { bmMemmove(b, 16) }
|
||||||
func BenchmarkMemmove32(b *testing.B) { bmMemmove(32, b) }
|
func BenchmarkMemmove32(b *testing.B) { bmMemmove(b, 32) }
|
||||||
func BenchmarkMemmove64(b *testing.B) { bmMemmove(64, b) }
|
func BenchmarkMemmove64(b *testing.B) { bmMemmove(b, 64) }
|
||||||
func BenchmarkMemmove128(b *testing.B) { bmMemmove(128, b) }
|
func BenchmarkMemmove128(b *testing.B) { bmMemmove(b, 128) }
|
||||||
func BenchmarkMemmove256(b *testing.B) { bmMemmove(256, b) }
|
func BenchmarkMemmove256(b *testing.B) { bmMemmove(b, 256) }
|
||||||
func BenchmarkMemmove512(b *testing.B) { bmMemmove(512, b) }
|
func BenchmarkMemmove512(b *testing.B) { bmMemmove(b, 512) }
|
||||||
func BenchmarkMemmove1024(b *testing.B) { bmMemmove(1024, b) }
|
func BenchmarkMemmove1024(b *testing.B) { bmMemmove(b, 1024) }
|
||||||
func BenchmarkMemmove2048(b *testing.B) { bmMemmove(2048, b) }
|
func BenchmarkMemmove2048(b *testing.B) { bmMemmove(b, 2048) }
|
||||||
func BenchmarkMemmove4096(b *testing.B) { bmMemmove(4096, b) }
|
func BenchmarkMemmove4096(b *testing.B) { bmMemmove(b, 4096) }
|
||||||
|
|
||||||
|
func TestMemclr(t *testing.T) {
|
||||||
|
size := 512
|
||||||
|
if testing.Short() {
|
||||||
|
size = 128 + 16
|
||||||
|
}
|
||||||
|
mem := make([]byte, size)
|
||||||
|
for i := 0; i < size; i++ {
|
||||||
|
mem[i] = 0xee
|
||||||
|
}
|
||||||
|
for n := 0; n < size; n++ {
|
||||||
|
for x := 0; x <= size-n; x++ { // offset in mem
|
||||||
|
MemclrBytes(mem[x : x+n])
|
||||||
|
for i := 0; i < x; i++ {
|
||||||
|
if mem[i] != 0xee {
|
||||||
|
t.Fatalf("overwrite prefix mem[%d] = %d", i, mem[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i := x; i < x+n; i++ {
|
||||||
|
if mem[i] != 0 {
|
||||||
|
t.Fatalf("failed clear mem[%d] = %d", i, mem[i])
|
||||||
|
}
|
||||||
|
mem[i] = 0xee
|
||||||
|
}
|
||||||
|
for i := x + n; i < size; i++ {
|
||||||
|
if mem[i] != 0xee {
|
||||||
|
t.Fatalf("overwrite suffix mem[%d] = %d", i, mem[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func bmMemclr(b *testing.B, n int) {
|
||||||
|
x := make([]byte, n)
|
||||||
|
b.SetBytes(int64(n))
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
MemclrBytes(x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func BenchmarkMemclr5(b *testing.B) { bmMemclr(b, 5) }
|
||||||
|
func BenchmarkMemclr16(b *testing.B) { bmMemclr(b, 16) }
|
||||||
|
func BenchmarkMemclr64(b *testing.B) { bmMemclr(b, 64) }
|
||||||
|
func BenchmarkMemclr256(b *testing.B) { bmMemclr(b, 256) }
|
||||||
|
func BenchmarkMemclr4096(b *testing.B) { bmMemclr(b, 4096) }
|
||||||
|
func BenchmarkMemclr65536(b *testing.B) { bmMemclr(b, 65536) }
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue