filter: add benchmark and pass linting

This commit is contained in:
Markus Tzoe 2017-07-21 19:26:11 +08:00
parent 2fd0e8f2d8
commit 03aaac588f
5 changed files with 124 additions and 48 deletions

View file

@ -10,6 +10,7 @@ const (
cpuArchSSE4
)
// CPUArch indicates currently cpu architecture: 0 general; 1 sse2 enabled; 2 sse4 enabled.
var CPUArch = cpuArchUNKNOWN
func init() {

View file

@ -4,6 +4,7 @@ import (
"unsafe"
)
// Filter exposes Decode and Encode methods for data manipulation
type Filter interface {
Decode(*int32)
Encode(*int32)
@ -21,30 +22,31 @@ type flt struct {
encode func(*int32)
}
// New creates a Filter based on current CPUArch
func New(data [8]byte, shift uint32) Filter {
t := flt{}
t.shift = shift
t.round = 1 << uint32(shift-1)
t.qm[0] = int32(int8(data[0]))
t.qm[1] = int32(int8(data[1]))
t.qm[2] = int32(int8(data[2]))
t.qm[3] = int32(int8(data[3]))
t.qm[4] = int32(int8(data[4]))
t.qm[5] = int32(int8(data[5]))
t.qm[6] = int32(int8(data[6]))
t.qm[7] = int32(int8(data[7]))
f := flt{}
f.shift = shift
f.round = 1 << uint32(shift-1)
f.qm[0] = int32(int8(data[0]))
f.qm[1] = int32(int8(data[1]))
f.qm[2] = int32(int8(data[2]))
f.qm[3] = int32(int8(data[3]))
f.qm[4] = int32(int8(data[4]))
f.qm[5] = int32(int8(data[5]))
f.qm[6] = int32(int8(data[6]))
f.qm[7] = int32(int8(data[7]))
switch CPUArch {
case cpuArchSSE4:
t.decode = t.DecodeSSE4
t.encode = t.EncodeSSE4
f.decode = f.DecodeSSE4
f.encode = f.EncodeSSE4
case cpuArchSSE2:
t.decode = t.DecodeSSE2
t.encode = t.EncodeSSE2
f.decode = f.DecodeSSE2
f.encode = f.EncodeSSE2
default:
t.decode = t.DecodeCompat
t.encode = t.EncodeCompat
f.decode = f.DecodeCompat
f.encode = f.EncodeCompat
}
return &t
return &f
}
func (f *flt) Decode(in *int32) {
@ -56,27 +58,27 @@ func (f *flt) Encode(in *int32) {
}
func (f *flt) DecodeSSE4(in *int32) {
__hybrid_filter_dec_sse4(unsafe.Pointer(in), unsafe.Pointer(&f.error), unsafe.Pointer(&f.qm[0]), unsafe.Pointer(&f.dx[0]), unsafe.Pointer(&f.dl[0]), f.round, f.shift)
_HybridFilterDecSSE4(unsafe.Pointer(in), unsafe.Pointer(&f.error), unsafe.Pointer(&f.qm[0]), unsafe.Pointer(&f.dx[0]), unsafe.Pointer(&f.dl[0]), f.round, f.shift)
}
func (f *flt) EncodeSSE4(in *int32) {
__hybrid_filter_enc_sse4(unsafe.Pointer(in), unsafe.Pointer(&f.error), unsafe.Pointer(&f.qm[0]), unsafe.Pointer(&f.dx[0]), unsafe.Pointer(&f.dl[0]), f.round, f.shift)
_HybridFilterEncSSE4(unsafe.Pointer(in), unsafe.Pointer(&f.error), unsafe.Pointer(&f.qm[0]), unsafe.Pointer(&f.dx[0]), unsafe.Pointer(&f.dl[0]), f.round, f.shift)
}
func (f *flt) DecodeSSE2(in *int32) {
__hybrid_filter_dec_sse2(unsafe.Pointer(in), unsafe.Pointer(&f.error), unsafe.Pointer(&f.qm[0]), unsafe.Pointer(&f.dx[0]), unsafe.Pointer(&f.dl[0]), f.round, f.shift)
_HybridFilterDecSSE2(unsafe.Pointer(in), unsafe.Pointer(&f.error), unsafe.Pointer(&f.qm[0]), unsafe.Pointer(&f.dx[0]), unsafe.Pointer(&f.dl[0]), f.round, f.shift)
}
func (f *flt) EncodeSSE2(in *int32) {
__hybrid_filter_enc_sse2(unsafe.Pointer(in), unsafe.Pointer(&f.error), unsafe.Pointer(&f.qm[0]), unsafe.Pointer(&f.dx[0]), unsafe.Pointer(&f.dl[0]), f.round, f.shift)
_HybridFilterEncSSE2(unsafe.Pointer(in), unsafe.Pointer(&f.error), unsafe.Pointer(&f.qm[0]), unsafe.Pointer(&f.dx[0]), unsafe.Pointer(&f.dl[0]), f.round, f.shift)
}
func (t *flt) DecodeCompat(in *int32) {
pa := t.dl[:]
pb := t.qm[:]
pm := t.dx[:]
sum := t.round
if t.error < 0 {
func (f *flt) DecodeCompat(in *int32) {
pa := f.dl[:]
pb := f.qm[:]
pm := f.dx[:]
sum := f.round
if f.error < 0 {
pb[0] -= pm[0]
pb[1] -= pm[1]
pb[2] -= pm[2]
@ -85,7 +87,7 @@ func (t *flt) DecodeCompat(in *int32) {
pb[5] -= pm[5]
pb[6] -= pm[6]
pb[7] -= pm[7]
} else if t.error > 0 {
} else if f.error > 0 {
pb[0] += pm[0]
pb[1] += pm[1]
pb[2] += pm[2]
@ -111,8 +113,8 @@ func (t *flt) DecodeCompat(in *int32) {
pm[5] = ((pa[5] >> 30) | 2) & ^1
pm[6] = ((pa[6] >> 30) | 2) & ^1
pm[7] = ((pa[7] >> 30) | 4) & ^3
t.error = *in
*in += (sum >> uint32(t.shift))
f.error = *in
*in += (sum >> uint32(f.shift))
pa[4] = -pa[5]
pa[5] = -pa[6]
pa[6] = *in - pa[7]
@ -121,12 +123,12 @@ func (t *flt) DecodeCompat(in *int32) {
pa[4] += pa[5]
}
func (t *flt) EncodeCompat(in *int32) {
pa := t.dl[:]
pb := t.qm[:]
pm := t.dx[:]
sum := t.round
if t.error < 0 {
func (f *flt) EncodeCompat(in *int32) {
pa := f.dl[:]
pb := f.qm[:]
pm := f.dx[:]
sum := f.round
if f.error < 0 {
pb[0] -= pm[0]
pb[1] -= pm[1]
pb[2] -= pm[2]
@ -135,7 +137,7 @@ func (t *flt) EncodeCompat(in *int32) {
pb[5] -= pm[5]
pb[6] -= pm[6]
pb[7] -= pm[7]
} else if t.error > 0 {
} else if f.error > 0 {
pb[0] += pm[0]
pb[1] += pm[1]
pb[2] += pm[2]
@ -170,6 +172,6 @@ func (t *flt) EncodeCompat(in *int32) {
pa[5] += pa[6]
pa[4] += pa[5]
*in -= (sum >> uint32(t.shift))
t.error = *in
*in -= (sum >> uint32(f.shift))
f.error = *in
}

View file

@ -8,13 +8,13 @@ import (
)
//go:noescape
func __hybrid_filter_dec_sse4(in, err, qm, dx, dl unsafe.Pointer, round int32, shift uint32)
func _HybridFilterDecSSE4(in, err, qm, dx, dl unsafe.Pointer, round int32, shift uint32)
//go:noescape
func __hybrid_filter_enc_sse4(in, err, qm, dx, dl unsafe.Pointer, round int32, shift uint32)
func _HybridFilterEncSSE4(in, err, qm, dx, dl unsafe.Pointer, round int32, shift uint32)
//go:noescape
func __hybrid_filter_dec_sse2(in, err, qm, dx, dl unsafe.Pointer, round int32, shift uint32)
func _HybridFilterDecSSE2(in, err, qm, dx, dl unsafe.Pointer, round int32, shift uint32)
//go:noescape
func __hybrid_filter_enc_sse2(in, err, qm, dx, dl unsafe.Pointer, round int32, shift uint32)
func _HybridFilterEncSSE2(in, err, qm, dx, dl unsafe.Pointer, round int32, shift uint32)

View file

@ -7,7 +7,7 @@ DATA LCDATA1<>+0x010(SB)/8, $0xfffffffeffffffff
DATA LCDATA1<>+0x018(SB)/8, $0xfffffffcfffffffe
GLOBL LCDATA1<>(SB), 8, $32
TEXT ·__hybrid_filter_dec_sse4(SB), $16-56
TEXT ·_HybridFilterDecSSE4(SB), $16-56
MOVQ in+0(FP), DI
MOVQ err+8(FP), SI
@ -93,7 +93,7 @@ DATA LCDATA2<>+0x010(SB)/8, $0xfffffffeffffffff
DATA LCDATA2<>+0x018(SB)/8, $0xfffffffcfffffffe
GLOBL LCDATA2<>(SB), 8, $32
TEXT ·__hybrid_filter_enc_sse4(SB), $16-56
TEXT ·_HybridFilterEncSSE4(SB), $16-56
MOVQ in+0(FP), DI
MOVQ err+8(FP), SI
@ -180,7 +180,7 @@ DATA LCDATA3<>+0x010(SB)/8, $0xfffffffeffffffff
DATA LCDATA3<>+0x018(SB)/8, $0xfffffffcfffffffe
GLOBL LCDATA3<>(SB), 8, $32
TEXT ·__hybrid_filter_dec_sse2(SB), $16-56
TEXT ·_HybridFilterDecSSE2(SB), $16-56
MOVQ in+0(FP), DI
MOVQ err+8(FP), SI
@ -278,7 +278,7 @@ DATA LCDATA4<>+0x010(SB)/8, $0xfffffffeffffffff
DATA LCDATA4<>+0x018(SB)/8, $0xfffffffcfffffffe
GLOBL LCDATA4<>(SB), 8, $32
TEXT ·__hybrid_filter_enc_sse2(SB), $16-56
TEXT ·_HybridFilterEncSSE2(SB), $16-56
MOVQ in+0(FP), DI
MOVQ err+8(FP), SI

73
filter/filter_test.go Normal file
View file

@ -0,0 +1,73 @@
package filter
import (
"testing"
)
func newFlt() *flt {
t := flt{}
t.shift = 8
t.round = 1 << uint32(t.shift-1)
t.qm = [8]int32{1, 2, 3, 4, 5, 6, 7, 8}
return &t
}
func BenchmarkEncodeSSE4(b *testing.B) {
f := newFlt()
var in int32
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
f.EncodeSSE4(&in)
}
})
}
func BenchmarkEncodeSSE2(b *testing.B) {
f := newFlt()
var in int32
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
f.EncodeSSE2(&in)
}
})
}
func BenchmarkEncodeCompat(b *testing.B) {
f := newFlt()
var in int32
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
f.EncodeCompat(&in)
}
})
}
func BenchmarkDecodeSSE4(b *testing.B) {
f := newFlt()
var in int32
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
f.DecodeSSE4(&in)
}
})
}
func BenchmarkDecodeSSE2(b *testing.B) {
f := newFlt()
var in int32
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
f.DecodeSSE2(&in)
}
})
}
func BenchmarkDecodeCompat(b *testing.B) {
f := newFlt()
var in int32
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
f.DecodeCompat(&in)
}
})
}