@@ -23,6 +23,7 @@ import (
2323 "fmt"
2424 "os"
2525 "runtime"
26+ "strconv"
2627 "strings"
2728
2829 "golang.org/x/sys/unix"
@@ -106,12 +107,12 @@ func getCPUVariantFromArch(arch string) (string, error) {
106107 return variant , nil
107108}
108109
109- // getCPUVariant returns cpu variant for ARM
110+ // getArmCPUVariant returns cpu variant for ARM
110111// We first try reading "Cpu architecture" field from /proc/cpuinfo
111112// If we can't find it, then fall back using a system call
112113// This is to cover running ARM in emulated environment on x86 host as this field in /proc/cpuinfo
113114// was not present.
114- func getCPUVariant () (string , error ) {
115+ func getArmCPUVariant () (string , error ) {
115116 variant , err := getCPUInfo ("Cpu architecture" )
116117 if err != nil {
117118 if errors .Is (err , errNotFound ) {
@@ -158,3 +159,40 @@ func getCPUVariant() (string, error) {
158159
159160 return variant , nil
160161}
162+
163+ func getAmd64MicroArchLevel () (string , error ) {
164+ flags , err := getCPUInfo ("flags" )
165+ if errors .Is (err , errNotFound ) {
166+ return "" , fmt .Errorf ("failure getting CPU flags: %v" , err )
167+ }
168+
169+ containsAll := func (set map [string ]interface {}, toMatch []string ) bool {
170+ for _ , m := range toMatch {
171+ if _ , ok := set [m ]; ! ok {
172+ return false
173+ }
174+ }
175+ return true
176+ }
177+
178+ flagSet := map [string ]interface {}{}
179+ for _ , flag := range strings .Split (flags , " " ) {
180+ flagSet [flag ] = true
181+ }
182+
183+ // https://unix.stackexchange.com/questions/631217/how-do-i-check-if-my-cpu-supports-x86-64-v2
184+ level := 1
185+ if containsAll (flagSet , []string {"lm" , "cmov" , "cx8" , "fpu" , "fxsr" , "mmx" , "syscall" , "sse2" }) {
186+ level = 1
187+ }
188+ if level == 1 && containsAll (flagSet , []string {"cx16" , "lahf_lm" , "popcnt" , "sse4_1" , "sse4_2" , "ssse3" }) {
189+ level = 2
190+ }
191+ if level == 2 && containsAll (flagSet , []string {"avx" , "avx2" , "bmi1" , "bmi2" , "f16c" , "fma" , "abm" , "movbe" , "xsave" }) {
192+ level = 3
193+ }
194+ if level == 3 && containsAll (flagSet , []string {"avx512f" , "avx512bw" , "avx512cd" , "avx512dq" , "avx512vl" }) {
195+ level = 4
196+ }
197+ return "v" + strconv .Itoa (level ), nil
198+ }
0 commit comments