そこで書いてみました。結果、自分のPCは中古なのでSVX2まで対応でした。
それでも単精度の浮動小数点なら1度に8つの積+和が出来てしまいます。→ 実際にSIMD命令を使った関数
以下の使い方は GetSSE を呼び出すと列挙型が帰るので 使いたい命令があるかどうかは
if 使いたい命令 in GetSSE() then 〜
表示するなら対応する SSEname に文字列を用意しています。
var i: TSSEMODE; s:string;
begin
s:=''; for i := low(SSEname) to High(SSEname) do
if i in d then s := s + ' ' + SSEname[i];
昔にdelphiで作ったものを引っ張りだして修正したので sseに固執した名前付けだったり Lazarusなのにintelアセンブラ書式なのはご容赦下さい 。
以下がGetSSE
{$ASMMODE intel}
type
TSSEMODE = (sseSSE2, sseSSE3, sseFMA, sseSSE41, sseSSE42, sseAVX, sseAVX2, sseAVX512F, sseAVX512DQ);
TSSEMODEset = set of TSSEMODE;
const SSEname: array [low(TSSEMODE)..High(TSSEMODE)] of string =
('SSE2', 'SSE3', 'FMA', 'SSE41', 'SSE42', 'AVX', 'AVX2', 'AVX512F', 'AVX512DQ');
function GetSSE(): TSSEMODEset;
var iSZ, iDX, iCX, iBX: DWORD;
begin
asm
MOV EAX,0
CPUID
MOV iSZ,EAX
MOV EAX,1
CPUID
MOV iDX,EDX
MOV iCX,ECX
MOV EAX,7
MOV ECX,0
CPUID
MOV iBX,EBX
end ['EAX', 'ECX', 'EDX', 'EBX'];
if iSZ < 7 then iBX := 0;
Result := [];
if (iDX and (1 shl 26)) <> 0 then Include(Result, sseSSE2);
if (iCX and (1 shl 0)) <> 0 then Include(Result, sseSSE3);
if (iCX and (1 shl 12)) <> 0 then Include(Result, sseFMA);
if (iCX and (1 shl 19)) <> 0 then Include(Result, sseSSE41);
if (iCX and (1 shl 20)) <> 0 then Include(Result, sseSSE42);
if (iCX and (1 shl 28)) <> 0 then Include(Result, sseAVX);
if (iBX and (1 shl 5)) <> 0 then Include(Result, sseAVX2);
if (iBX and (1 shl 16)) <> 0 then Include(Result, sseAVX512F);
if (iBX and (1 shl 17)) <> 0 then Include(Result, sseAVX512DQ);
end;
【このカテゴリーの最新記事】
- no image
- no image
- no image
- no image