AVX支持是否意味着支持BMI1?

3

我有一些依赖于AVX的代码。
在同一代码库中,我还使用了TZCNT.
后者是BMI1的一部分。我知道我可以使用CPUID测试此指令,但我很懒,所以我没有实际实现它。

为了测试支持,我只需执行一个AVX指令。如果我得到一个#UD未定义指令异常,我就知道CPU不支持AVX。
然而,tzcntbsf(或bsr - 我总是忘记哪个是哪个)向后兼容,因此不会触发异常。

如果我支持AVX,那是否意味着我支持BMI1
录音记录,我现在测试的CPU上没有AVX2。


1
即使您不想测试BMI支持,当您不关心输入为0时,通常应使用tzcntrep bsf)。在AMD CPU上,tzcntbsf快得多。在Intel Skylake(及以后?)上,它避免了bsf对只写目标寄存器的错误依赖。 (popcnt仍然具有SKL上的错误依赖,就像早期Intel CPU上的lz/tzcnt一样。) - Peter Cordes
1个回答

4
不,AVX支持并不意味着支持BMI1。
请参考以下表格以了解详细信息:
          Intel          AMD                  Year
---------------------------------------------------
AVX      Sandy Bridge    Bulldozer           2011
---------------------------------------------------
BMI1     Haswell         Piledriver/Jaguar   2013
---------------------------------------------------
ABM                      Barcelona           2007
         Haswell                             2013
---------------------------------------------------
AVX2     Haswell                             2013
                         Carrizo             2015
                         Ryzen               2017
---------------------------------------------------
BMI2     Haswell                             2013
                         Excavator           2015
                         Ryzen               2017

大多数处理器都支持这两种指令,但AVX比BMI1早两年。
此外,tzcntbsf在标志方面有不同的语义。
如果您想强制引发#UD异常,可以使用andn

来源:维基百科:BMI, AVX

如果您想使用CPUID:

BMI1 -> CPUID.(EAX=07H, ECX=0H):EBX.BMI1[bit 3]
(ANDN, BEXTR, BLSI, BLSMSK, BLSR, TZCNT)

BMI2  -> CPUID.(EAX=07H, ECX=0H):EBX.BMI2[bit 8]
(BZHI, MULX, PDEP, PEXT, RORX, SARX, SHLX, SHRX)

LZCNT -> CPUID.(EAX=80000001H) ECX.LZCNT[bit 5]  

POPCNT -> CPUID.(EAX=01H) :ECX.POPCNT [Bit 23]

请注意,即使CPUID指示(Intel)处理器不支持popcnt,它通常也会支持。

如果您想将它们添加到您的答案中:BMI1 (ANDN, BEXTR, BLSI, BLSMSK, BLSR, TZCNT) -> CPUID.(EAX=07H, ECX=0H):EBX.BMI1[位 3] BMI2 (BZHI, MULX, PDEP, PEXT, RORX, SARX, SHLX, SHRX) -> CPUID.(EAX=07H, ECX=0H):EBX.BMI2[位 8] LZCNT -> CPUID.EAX=80000001H:ECX.LZCNT[位 5]。这是英特尔术语:CPUID.EAX=80000001H:ECX.LZCNT[位 5]表示 AMD 处理器上的 ABM(即 popcnt + lzcnt)(因为 popcnt 有自己的 CPUID 位,而 ABM -> popcnt 而不是反过来)。 - Margaret Bloom
1
我不确定andn是否在所有地方都会陷入。毕竟,VEX前缀只是lds,我不确定所有旧的CPU在看到具有无效操作数组合的lds时是否会引发异常。但是,在64位模式下,这不应该是一个问题,因为lds和les是非法的。 - fuz
1
哪些英特尔CPU可以正确执行popcnt但不设置CPUID功能位?在我的第一代Core2(Conroe / Merom:SSSE3但不是SSE4.1)上会出现故障。 - Peter Cordes
1
虚拟机可以暴露任何组合的CPUID标志。尽管启用BMI而不启用AVX的可能性要大得多,因为AVX意味着额外的体系结构状态。因此,在方便的时候,您应该避免基于已发布的硬件做出假设。(这对于决定创建哪个版本的函数是相关的,例如,在AVX版本的函数中依赖于BMI是有意义的。但在进行运行时CPU检测时,您应该测试所有相关的特征位。) - Peter Cordes
你只需要在初始化时进行一次CPU特性检测,并在全局位域中设置标志。这样做非常便宜,而且您永远不必担心检查的成本。 - Cody Gray
@CodyGray,我通常会这样做,但在性能测试短代码片段时,依靠自动记录的#UD异常更容易。 - Johan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接