diff --git a/sei-db/state_db/sc/flatkv/lthash/backend_simd_amd64.go b/sei-db/state_db/sc/flatkv/lthash/backend_simd_amd64.go index 8c689b5caf..4d78f56295 100644 --- a/sei-db/state_db/sc/flatkv/lthash/backend_simd_amd64.go +++ b/sei-db/state_db/sc/flatkv/lthash/backend_simd_amd64.go @@ -12,6 +12,11 @@ import ( //go:generate go run gen_blake3_xof16.go +// vzeroupper clears the upper halves of the vector registers. +// +//go:noescape +func vzeroupper() + // simdBackendName is the name reported by ActiveBackend for the AVX-512 path. const simdBackendName = "simd" @@ -22,11 +27,24 @@ func simdBackend() (backend, bool) { if !archsimd.X86.AVX512() || !archsimd.X86.AVX512VBMI2() { return backend{}, false } + // The compiler emits no VZEROUPPER after AVX-512 code, and legacy-SSE code + // in the caller (memmove, SHA-NI) runs several times slower while the upper + // halves are dirty, so every kernel is wrapped here rather than trusting + // each one to clear them. return backend{ - name: simdBackendName, - expand: expandSIMD, - add: addSIMD, - sub: subSIMD, + name: simdBackendName, + expand: func(data []byte, dst *LtHash) { + expandSIMD(data, dst) + vzeroupper() + }, + add: func(dst, src *LtHash) { + addSIMD(dst, src) + vzeroupper() + }, + sub: func(dst, src *LtHash) { + subSIMD(dst, src) + vzeroupper() + }, }, true } diff --git a/sei-db/state_db/sc/flatkv/lthash/zeroupper_amd64.s b/sei-db/state_db/sc/flatkv/lthash/zeroupper_amd64.s new file mode 100644 index 0000000000..6c4dd6d709 --- /dev/null +++ b/sei-db/state_db/sc/flatkv/lthash/zeroupper_amd64.s @@ -0,0 +1,8 @@ +//go:build goexperiment.simd && amd64 + +#include "textflag.h" + +// func vzeroupper() +TEXT ·vzeroupper(SB), NOSPLIT, $0-0 + VZEROUPPER + RET