Files
p256k1/cpufeatures.go

61 lines
1.6 KiB
Go

//go:build amd64
package p256k1
import (
"sync"
"sync/atomic"
"github.com/klauspost/cpuid/v2"
)
// CPU feature flags
var (
// hasAVX2CPU indicates whether the CPU supports AVX2 instructions.
// This is detected at startup and never changes.
hasAVX2CPU bool
// avx2Disabled allows runtime disabling of AVX2 for testing/debugging.
// Uses atomic operations for thread-safety without locks on the fast path.
avx2Disabled atomic.Bool
// initOnce ensures CPU detection runs exactly once
initOnce sync.Once
)
func init() {
initOnce.Do(detectCPUFeatures)
}
// detectCPUFeatures detects CPU capabilities at startup
func detectCPUFeatures() {
hasAVX2CPU = cpuid.CPU.Has(cpuid.AVX2)
}
// HasAVX2 returns true if AVX2 is available and enabled.
// This is the function that should be called in hot paths to decide
// whether to use AVX2-optimized code paths.
func HasAVX2() bool {
return hasAVX2CPU && !avx2Disabled.Load()
}
// HasAVX2CPU returns true if the CPU supports AVX2, regardless of whether
// it's been disabled via SetAVX2Enabled.
func HasAVX2CPU() bool {
return hasAVX2CPU
}
// SetAVX2Enabled enables or disables the use of AVX2 instructions.
// This is useful for benchmarking to compare AVX2 vs non-AVX2 performance,
// or for debugging. Pass true to enable AVX2 (default), false to disable.
// This function is thread-safe.
func SetAVX2Enabled(enabled bool) {
avx2Disabled.Store(!enabled)
}
// IsAVX2Enabled returns whether AVX2 is currently enabled.
// Returns true if AVX2 is both available on the CPU and not disabled.
func IsAVX2Enabled() bool {
return HasAVX2()
}