トップへ(mam-mam.net/)

Delphi 掲示板~(サンプル投稿)Delphi 64ビットでアセンブラでSSEを使って同時4つの単精度浮動小数点演算を行うには

検索:

Delphi 掲示板

一覧に戻る

(サンプル投稿)Delphi 64ビットでアセンブラでSSEを使って同時4つの単精度浮動小数点演算を行うには

未解決
mam
(2024-05-23 17:34:33)
Delphiで64ビットコンパイルを行った場合のみですが、
アセンブラでSSE命令を使用すると同時4つの単精度浮動小数点演算が可能となり、
配列の演算が高速になるのですが、どのようなソースコードを記述すればよいでしょうか。
(サンプル返信)
(2024-05-23 18:00:28)
Delphi64Bitでインライン アセンブラ関数に渡される最初の 4 つのパラメータは、それぞれ RCX、RDX、R8、R9レジスタの順に渡されるそうです。
参考URL
https://docwiki.embarcadero.com/RADStudio/Alexandria/ja/%E3%82%A4%E3%83%B3%E3%83%A9%E3%82%A4%E3%83%B3_%E3%82%A2%E3%82%BB%E3%83%B3%E3%83%96%E3%83%AA_%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E4%BD%BF%E7%94%A8


//SSEで同時4つの浮動小数点演算を行う
//ans[0] := a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + a[3]*b[3]
procedure MulSum4(var ans, a, b: single);
asm
  MOVUPS  XMM1, [RDX]    //XMM1=a[0..3]
  MOVUPS  XMM2, [R8]     //XMM2=b[0..3]
  DPPS    XMM2, XMM1,$f1 //XMM2=SUM(XMM2*XMM1)
  MOVUPS  [RCX], XMM2    //ans=XMM2
end;

procedure TForm1.Button1Click(Sender:TObject);
var ans,a,b:array[0..3] of single;
begin
  a[0]:=1.0; a[1]:=1.2; a[2]:=1.3; a[3]:=1.0;
  b[0]:=1.1; b[1]:=1.0; b[2]:=1.0; b[3]:=1.4;
  MulSum4(ans[0], a[0], b[0]);
  ShowMessage(FloatToStr(ans[0]));
end;


//SSEで同時4つの浮動小数点演算を行う
//ans[0]:=a[0]*b[0], ans[1]:=a[1]*b[1],
//ans[2]:=a[2]*b[2], ans[3]:=a[3]*b[3]
procedure Mul4(var ans, a, b: single);
asm
  MOVUPS  XMM0, [RDX]    //XMM0 = a[0..3]
  MOVUPS  XMM1, [R8]     //XMM1 = b[0..3]
  MULPS   XMM1, XMM0     //XMM1 = XMM1 * XMM0
  MOVUPS  [RCX], XMM1    //ans = XMM1
end;

procedure TForm1.Button2Click(Sender: TObject);
var ans,a,b:array[0..3] of single;
begin
  a[0]:=1.0; a[1]:=1.2; a[2]:=1.3; a[3]:=1.0;
  b[0]:=1.1; b[1]:=1.0; b[2]:=1.0; b[3]:=1.4;
  Mul4(ans[0], a[0], b[0]);
  ShowMessage(
    FloatToStr(ans[0])+#13#10+
    FloatToStr(ans[1])+#13#10+
    FloatToStr(ans[2])+#13#10+
    FloatToStr(ans[3])
  );
end;


//SSEで同時4つの浮動小数点演算を行う
//ans[0]:=ans[0]+a[0]*b[0], ans[1]:=ans[1]+a[1]*b[1],
//ans[2]:=ans[2]+a[2]*b[2], ans[3]:=ans[3]+a[3]*b[3]
procedure AddMul4(var ans, a, b: single);
asm  //               RCX  RDX  R8
      MOVUPS  XMM0, [RCX]    //XMM0=ans[0..3]
      MOVUPS  XMM1, [RDX]    //XMM1=a[0..3]
      MOVUPS  XMM2, [R8]     //XMM2=b[0..3]
      MULPS   XMM2, XMM1     //XMM2=XMM2*XMM1
      ADDPS   XMM2, XMM0     //XMM2=XMM2+XMM0
      MOVUPS  [RCX],XMM2     //ans=XMM2
end;

procedure TForm1.Button3Click(Sender: TObject);
var ans,a,b:array[0..3] of single;
begin
  ans[0]:=0.0; ans[1]:=1.0; ans[2]:=1.0; ans[3]:=2.0;
  a[0]:=1.0; a[1]:=1.2; a[2]:=1.3; a[3]:=1.0;
  b[0]:=1.1; b[1]:=1.0; b[2]:=1.0; b[3]:=1.4;
  AddMul4(ans[0], a[0], b[0]);
  ShowMessage(
    FloatToStr(ans[0])+#13#10+
    FloatToStr(ans[1])+#13#10+
    FloatToStr(ans[2])+#13#10+
    FloatToStr(ans[3])
  );
end;


ターゲット プラットフォームにWindows64ビットを追加して、64ビットでコンパイルしてください。

返信

名前
1~16文字
質問に対する返信
1~4000文字
解決
解決時にON
返信