2017-06-29 105 views
3

我有一些依賴於AVX的代碼。
在相同的代碼庫中,我也使用TZCNT
後者是BMI1的一部分。我知道我可以使用CPUID來測試這條指令,但我很懶,所以我沒有真正實現它。AVX支持是否意味着支持BMI1?

要測試支持,我只需執行AVX指令。如果我得到一個#UD未定義的指令異常,我知道CPU不支持AVX。
但是tzcntbsf(或bsr - 我總是忘記哪個是哪個)向後兼容(種類),所以不會觸發異常。

如果我有AVX支持,是不是暗示支持BMI1
爲了記錄,我沒有在我現在正在測試的CPU上使用AVX2。

+1

即使您不想測試BMI支持,當您不關心input = 0的行爲時,通常應該使用'tzcnt'('rep bsf')。 'tzcnt'比AMD CPU上的'bsf'快很多。在Intel Skylake(以及後續版本)上,它避免了對'bsf'具有的只寫目標寄存器的錯誤依賴。 ('popcnt'在SKL上仍然存在虛假dep,就像早期Intel CPU上的lz/tzcnt一樣。) –

回答

3

不,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

來源:維基百科:BMIAVX

如果你想使用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經常做。

+0

如果您想將它們添加到您的答案:** BMI1 ** *(ANDN,BEXTR,BLSI ,BLSMSK,BLSR,TZCNT)* - >'CPUID。(EAX = 07H,ECX = 0H):EBX.BMI1 [bit 3] ** ** BMI2 ** *(BZHI,MULX,PDEP,PEXT,RORX,SARX, (EAX = 07H,ECX = 0H):EBX.BMI2 [bit 8] ** ** LZCNT ** - >'CPUID.EAX = 80000001H:ECX.LZCNT [bit 5]' 。這是英特爾的術語:'CPUID.EAX = 80000001H:ECX.LZCNT [bit 5]'表示AMD處理器上的ABM(即'popcnt' +'lzcnt')(因爲'popcnt'有它自己的CPUID位和ABM->' popcnt「,但不能反過來)。 –

+1

我不確定'andn'陷阱到處都是。 VEX前綴完全是lds,我不確定是否所有舊的CPU在看到具有無效操作數組合的lds時都會引發異常。儘管在64位模式下,這應該不是問題,因爲lds和les是非法的。 – fuz

+1

哪些英特爾CPU可以正確執行'popcnt',但不要設置CPUID功能位?它在我的第一代Core2上出錯(Conroe/Merom:SSSE3,但不是SSE4.1)。 –