go 建议:x/sys/cpu:暴露运行时AMD64微架构级别

bksxznpy  于 5个月前  发布在  Go
关注(0)|答案(5)|浏览(75)

在包golang.org/x/sys/cpu中添加一个int符号0-4,该符号暴露运行程序的机器的AMD64微架构级别。
参考资料:

  • https://zh.wikipedia.org/wiki/X86-64#微架构级别
  • https://go.dev/doc/go1.18#amd64
  • github.com/klauspost/cpuid/v2 CPUInfo.X64Level
xjreopfe

xjreopfe1#

值得注意的是,这些信息已经作为构建标签提供,例如 //go:build amd64.v3。有没有整数值会有所帮助的情况?
此外,这将是一个常量还是一个变量?我认为这是一个常量更好,因为它在构建时是已知的。

aelbi1ox

aelbi1ox2#

如果理解正确的话,值在构建时是未知的。在构建时,我们知道最低支持的微架构级别,这是从GOAMD64环境变量中获取的。但是在运行时,我们知道实际的微架构级别,它必须至少与此相同,但可能更高。同样,构建标签在这里也没有帮助。

2eafrhcq

2eafrhcq3#

啊,这个API实际上会获取运行程序的机器的级别,这可能比二进制文件构建的级别要高。我现在明白了区别。

pkln4tw6

pkln4tw64#

我认为通常最好直接在运行时指定应该阻止优化代码路径的具体特征,而不是使用微架构级别。这样,优化的代码可能会更频繁地被触发,因为它不是基于某些指令的支持而是有条件的。

例如,LZCNT和BMI可以在没有AVX2支持的情况下使用。

示例代码:

// internal/cpu:sha1block_amd64.go
package sha1

// Line 15 in [0cd309e](https://github.com/golang/go/commit/0cd309e12818f988693bf8e4d9f1453331dcf9f2)
func (s *state) amd64SHA1Block(in []byte, digest *digest) {
 var useAVX2 = s.c.X86.HasAVX2 && s.c.X86.HasBMI1 && s.c.X86.HasBMI2
 // ...
}
puruo6ea

puruo6ea5#

这个用途的一个例子是在多个为不同GOAMD64值编译的二进制文件中选择一个。我目前在https://github.com/CAFxX/mgo中使用klauspost/cpuid来实现这个目的。

相关问题