如果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;发布于 2017-01-05 02:23:05
基本上,在使用AVX2之前,您需要检查
如果通过检查CPUID来支持AVX2指令集,则为
启用了YMM寄存器的使用,则为:EBX.AVX2bit 5=1
例如,可以使用此函数完成步骤1:
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;
例如,可以使用以下函数来完成步骤2:
function OSEnabledXmmYmm: boolean;
// necessary to check before using AVX, FMA or AES instructions!
asm
{$IFDEF CPUx86}
push ebx
{$ELSE CPUx64}
mov r10, rbx
{$ENDIF}
mov eax,1
cpuid
bt ecx, 27 // CPUID.1:ECX.OSXSAVE[bit 27] = 1 (XGETBV enabled for application use; implies XGETBV is an available instruction also)
jnc @not_supported
xor ecx,ecx //Specify control register XCR0 = XFEATURE_ENABLED_MASK register
db 0Fh, 01h, 0D0h // xgetbv //Reads XCR (extended control register) -> EDX:EAX
{lgdt eax = db 0Fh, 01h = privileged instruction, so don't go here unless xgetbv is allowed}
//CHECK XFEATURE_ENABLED_MASK[2:1] = ‘11b’
and eax, 06h //06h= 00000000000000000000000000000110b
cmp eax, 06h//; check OS has enabled both XMM (bit 1) and YMM (bit 2) state management support
jne @not_supported
mov eax,1
jmp @out
@not_supported:
xor eax,eax
@out:
{$IFDEF CPUx86}
pop ebx
{$ELSE CPUx64}
mov rbx, r10
{$ENDIF}
end;
Of course, you can also use this to modify the function you posted to just have a single function to call.发布于 2017-01-05 02:28:21
好的,我认为检测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;https://stackoverflow.com/questions/41468871
复制相似问题