Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly AVX支持是否意味着BMI1支持?_Assembly_X86_64 Bit_Avx_Bmi - Fatal编程技术网

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

Assembly AVX支持是否意味着BMI1支持?,assembly,x86,64-bit,avx,bmi,Assembly,X86,64 Bit,Avx,Bmi,我有一些依赖AVX的代码。 在相同的代码库中,我还使用了TZCNT 后者是BMI1的一部分。我知道我可以使用CPUID测试这个指令,但我很懒,所以我没有真正实现它 为了测试支持,我只需执行一条AVX指令。如果我得到#UD未定义指令异常,我知道CPU不支持AVX。 但是tzcnt与bsf(或bsr-我总是忘记哪个是哪个),因此不会触发异常 如果我有AVX支持,这是否意味着BMI1支持? 作为记录,我现在测试的CPU上没有AVX2 否,AVX支持并不意味着BMI1支持 详见下表:

我有一些依赖AVX的代码。
在相同的代码库中,我还使用了
TZCNT

后者是BMI1的一部分。我知道我可以使用CPUID测试这个指令,但我很懒,所以我没有真正实现它

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

如果我有
AVX
支持,这是否意味着
BMI1
支持?


作为记录,我现在测试的CPU上没有AVX2

否,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早两年。
除此之外,
tzcnt
bsf
对于标志具有不同的语义。
如果要强制执行
#UD
异常,可以使用

资料来源:维基百科:

如果要使用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指示(英特尔)处理器不支持
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.EAX=800000h:ECX->
。这是英特尔的术语:
CPUID.EAX=8000001h:ECX.LZCNT[bit 5]
表示AMD处理器上的ABM(即
popcnt
+
LZCNT
)(因为
popcnt
有自己的CPUID位和ABM->
popcnt
但不是相反)。我不确定
是否到处都有陷阱。VEX前缀毕竟只是lds,我不确定所有旧CPU在看到lds具有无效操作数组合时是否都会引发异常。但是,在64位模式下,这不应该是一个问题,因为lds和les是非法的。哪些英特尔CPU可以正确执行
popcnt
,但不设置CPUID功能位?它在我的第一代Core2(Conroe/Merom:SSSE3,但不是SSE4.1)上出现故障。虚拟机可以公开它们想要的任何CPUID标志组合。虽然他们在没有AVX的情况下启用BMI的可能性要比反之大得多,因为AVX意味着额外的体系结构状态。因此,在方便的时候,您应该避免根据已发布的硬件进行假设。(这与决定要创建的函数版本有关。例如,避免依赖AVX版本函数中的BMI是有意义的。但在执行运行时CPU检测时,应测试所有相关功能位。)您只需在初始化时执行一次CPU功能检测,并在全局位字段中设置标志。这样,它非常便宜,而且您永远不必担心检查的成本。即使您不想测试BMI支持,当您不关心输入为0时的行为时,通常也应该使用
tzcnt
rep bsf
tzcnt
比AMD CPU上的bsf
快得多。在英特尔Skylake(及更高版本?)上,它避免了对
bsf
所具有的只写目标寄存器的错误依赖。(
popcnt
在SKL上仍然有假dep,就像早期Intel CPU上的
lz/tzcnt
一样。)