From 712d6195df678890e06c8ffca145b3248b72f78f Mon Sep 17 00:00:00 2001 From: chenzhuoyu Date: Mon, 23 Aug 2021 14:25:51 +0800 Subject: [PATCH] fix: support AVX2 auto-detection for base64x --- decoder/assembler_amd64.go | 31 ++++++++++++++++++++++--------- encoder/assembler_amd64.go | 21 +++++++++++++++++---- go.mod | 4 ++-- go.sum | 8 ++++---- 4 files changed, 45 insertions(+), 19 deletions(-) diff --git a/decoder/assembler_amd64.go b/decoder/assembler_amd64.go index 8b0f17b..b40b0fd 100644 --- a/decoder/assembler_amd64.go +++ b/decoder/assembler_amd64.go @@ -24,6 +24,7 @@ import ( `unsafe` `github.com/bytedance/sonic/internal/caching` + `github.com/bytedance/sonic/internal/cpu` `github.com/bytedance/sonic/internal/jit` `github.com/bytedance/sonic/internal/native` `github.com/bytedance/sonic/internal/native/types` @@ -943,6 +944,10 @@ var ( _F_FieldMap_GetCaseInsensitive obj.Addr ) +const ( + _MODE_AVX2 = 1 << 2 +) + const ( _Fe_ID = int64(unsafe.Offsetof(caching.FieldEntry{}.ID)) _Fe_Name = int64(unsafe.Offsetof(caching.FieldEntry{}.Name)) @@ -1009,15 +1014,23 @@ func (self *_Assembler) _asm_OP_bin(_ *_Instr) { self.Emit("LEAQ" , jit.Sib(_SI, _SI, 2, 0), _SI) // LEAQ (SI)(SI*2), SI self.Emit("MOVQ" , _SI, jit.Ptr(_VP, 16)) // MOVQ SI, 16(VP) self.malloc(_SI, _SI) // MALLOC SI, SI - self.Emit("XORL" , _CX, _CX) // XORL CX, CX - self.Emit("XORL" , _DX, _DX) // XORL DX, DX - self.Emit("MOVQ" , _VP, _DI) // MOVQ VP, DI - self.Emit("XCHGQ", _SI, jit.Ptr(_VP, 0)) // XCHGQ SI, (VP) - self.Emit("XCHGQ", _DX, jit.Ptr(_VP, 8)) // XCHGQ DX, 8(VP) - self.call(_F_b64decode) // CALL b64decode - self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX - self.Sjmp("JS" , _LB_base64_error) // JS _base64_error - self.Emit("MOVQ" , _AX, jit.Ptr(_VP, 8)) // MOVQ AX, 8(VP) + + /* check for AVX2 support */ + if !cpu.HasAVX2 { + self.Emit("XORL", _CX, _CX) // XORL CX, CX + } else { + self.Emit("MOVL", jit.Imm(_MODE_AVX2), _CX) // MOVL $_MODE_AVX2, CX + } + + /* call the decoder */ + self.Emit("XORL" , _DX, _DX) // XORL DX, DX + self.Emit("MOVQ" , _VP, _DI) // MOVQ VP, DI + self.Emit("XCHGQ", _SI, jit.Ptr(_VP, 0)) // XCHGQ SI, (VP) + self.Emit("XCHGQ", _DX, jit.Ptr(_VP, 8)) // XCHGQ DX, 8(VP) + self.call(_F_b64decode) // CALL b64decode + self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX + self.Sjmp("JS" , _LB_base64_error) // JS _base64_error + self.Emit("MOVQ" , _AX, jit.Ptr(_VP, 8)) // MOVQ AX, 8(VP) } func (self *_Assembler) _asm_OP_bool(_ *_Instr) { diff --git a/encoder/assembler_amd64.go b/encoder/assembler_amd64.go index 2c8c107..e839800 100644 --- a/encoder/assembler_amd64.go +++ b/encoder/assembler_amd64.go @@ -22,6 +22,7 @@ import ( `strconv` `unsafe` + `github.com/bytedance/sonic/internal/cpu` `github.com/bytedance/sonic/internal/jit` `github.com/bytedance/sonic/internal/native/types` `github.com/twitchyliquid64/golang-asm/obj` @@ -803,6 +804,10 @@ var ( _F_encodeTextMarshaler obj.Addr ) +const ( + _MODE_AVX2 = 1 << 2 +) + func init() { _F_encodeTypedPointer = jit.Func(encodeTypedPointer) _F_encodeJsonMarshaler = jit.Func(encodeJsonMarshaler) @@ -908,10 +913,18 @@ func (self *_Assembler) _asm_OP_bin(_ *_Instr) { self.save_c() // SAVE $REG_ffi self.prep_buffer_c() // MOVE {buf}, DI self.Emit("MOVQ", _SP_p, _SI) // MOVQ SP.p, SI - self.Emit("XORL", _DX, _DX) // XORL DX, DX - self.call_c(_F_b64encode) // CALL b64encode - self.load_buffer() // LOAD {buf} - self.add_char('"') // CHAR $'"' + + /* check for AVX2 support */ + if !cpu.HasAVX2 { + self.Emit("XORL", _DX, _DX) // XORL DX, DX + } else { + self.Emit("MOVL", jit.Imm(_MODE_AVX2), _DX) // MOVL $_MODE_AVX2, DX + } + + /* call the encoder */ + self.call_c(_F_b64encode) // CALL b64encode + self.load_buffer() // LOAD {buf} + self.add_char('"') // CHAR $'"' } func (self *_Assembler) _asm_OP_quote(_ *_Instr) { diff --git a/go.mod b/go.mod index 3486e22..47a1fac 100644 --- a/go.mod +++ b/go.mod @@ -3,11 +3,11 @@ module github.com/bytedance/sonic go 1.15 require ( - github.com/chenzhuoyu/base64x v0.0.0-20210528162528-3c6c11c43ee5 + github.com/chenzhuoyu/base64x v0.0.0-20210823060942-dfd952a155c6 github.com/davecgh/go-spew v1.1.1 github.com/goccy/go-json v0.7.2 github.com/json-iterator/go v1.1.10 - github.com/klauspost/cpuid/v2 v2.0.6 + github.com/klauspost/cpuid/v2 v2.0.9 github.com/stretchr/testify v1.7.0 github.com/tidwall/gjson v1.8.0 github.com/twitchyliquid64/golang-asm v0.15.1 diff --git a/go.sum b/go.sum index 66a7327..47717bb 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/chenzhuoyu/base64x v0.0.0-20210528162528-3c6c11c43ee5 h1:7AStn2tanqGY99xzW+Ve1p6YYqnRr1m/yswJ4h0BhcY= -github.com/chenzhuoyu/base64x v0.0.0-20210528162528-3c6c11c43ee5/go.mod h1:NfDzX8KeqVNX62apij1OkqoeDdq1VR3g0TRZo99kkBA= +github.com/chenzhuoyu/base64x v0.0.0-20210823060942-dfd952a155c6 h1:sB+841K/1P6YcZTZQQBnj8B3b/gD1Km3ur/gtcpgA1o= +github.com/chenzhuoyu/base64x v0.0.0-20210823060942-dfd952a155c6/go.mod h1:Yj9Cv70aYHquW+Amrru9SJztDiIfOR4cn8bE7Vb5Gl0= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -8,8 +8,8 @@ github.com/goccy/go-json v0.7.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGF github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/klauspost/cpuid/v2 v2.0.6 h1:dQ5ueTiftKxp0gyjKSx5+8BtPWkyQbd95m8Gys/RarI= -github.com/klauspost/cpuid/v2 v2.0.6/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=