如何在Delphi中检测AVX2?

时间:2017-01-04 16:34:39

标签: delphi

如果CPU具有AVX1或AVX2,则以下代码返回True。有人知道如何修改此代码以准确检测AVX2指令支持吗?

function isAvxSupported: Boolean;
asm
{$IFDEF CPUX86}
    push ebx
{$ENDIF}
{$IFDEF CPUX64}
    mov r10, rbx
{$ENDIF}
    xor eax, eax
    cpuid
    cmp eax, 1
    jb @not_supported
    mov eax, 1
    cpuid
    and ecx, 018000000h
    cmp ecx, 018000000h
    jne @not_supported
    xor ecx, ecx
    db 0Fh, 01h, 0D0h //XGETBV
    and eax, 110b
    cmp eax, 110b
    jne @not_supported
    mov eax, 1
    jmp @done
@not_supported:
    xor eax, eax
@done:
{$IFDEF CPUX86}
    pop ebx
{$ENDIF}
{$IFDEF CPUX64}
    mov rbx, r10
{$ENDIF}
end;

2 个答案:

答案 0 :(得分:3)

基本上,在使用AVX2之前,您需要检查

  1. 如果通过检查CPUID支持AVX2指令集。(EAX = 07H,ECX = 0H):EBX.AVX2 [bit 5] = 1
  2. 如果OS启用了YMM寄存器
  3. 步骤1可以完成,例如使用此功能:

    ImageCell

    步骤2可以完成,例如使用此功能:

    
    function IsAVX2supported: boolean;
    asm
        // Save EBX
        {$IFDEF CPUx86}
          push ebx
        {$ELSE CPUx64}
          mov r10, rbx
        {$ENDIF}
        //Check CPUID.0
        xor eax, eax
        cpuid //modifies EAX,EBX,ECX,EDX
        cmp al, 7 // do we have a CPUID leaf 7 ?
        jge @Leaf7
          xor eax, eax
          jmp @Exit
        @Leaf7:
          //Check CPUID.7
          mov eax, 7h
          xor ecx, ecx
          cpuid
          bt ebx, 5 //AVX2: CPUID.(EAX=07H, ECX=0H):EBX.AVX2[bit 5]=1
          setc al
       @Exit:
       // Restore EBX
       {$IFDEF CPUx86}
         pop ebx
       {$ELSE CPUx64}
         mov rbx, r10
       {$ENDIF}
    end;
    

    当然,您也可以使用此功能修改您发布的功能,只需调用一个函数即可。

答案 1 :(得分:-1)

好的我认为检测AVX2就像这个一样简单

function isAVX2Supported():boolean;
var _ebx: Longword;
begin

  asm
    mov eax,7 // EAX=7 -> https://en.wikipedia.org/wiki/CPUID
    db $0F,$A2 // db $0F,$A2 = CPUID instruction
    mov _ebx,ebx
  end;
  if (_ebx and $20) = $20 then isAVX2Supported:=true //Bit 5 = 100000 = $20 (HEX) 
  else isAVX2Supported:=false;

end;