Difference between revisions of "SSE/de"

From Lazarus wiki
Jump to navigationJump to search
Line 4: Line 4:
 
Mit der SSE-Erweiterung der Modernen CPUs, kann bis zu 8-9fache Geschwindigkeitssteigerung erzielen, gegenüber klassischen FPU-Operationen.<br>
 
Mit der SSE-Erweiterung der Modernen CPUs, kann bis zu 8-9fache Geschwindigkeitssteigerung erzielen, gegenüber klassischen FPU-Operationen.<br>
 
Am besten werden 4x Vektoren und 4x4 Matrizen unterstützt, dies wird sehr viel bei OpenGL gebraucht. <br>
 
Am besten werden 4x Vektoren und 4x4 Matrizen unterstützt, dies wird sehr viel bei OpenGL gebraucht. <br>
Dies Assembler-Blöcke sind so angepasst, das sie auf 32Bit und 64Bit CPU laufen, voraus gesetzt, sie sind Intel kompatibel.  
+
Dies Assembler-Blöcke sind so angepasst, das sie auf 32Bit und 64Bit CPU laufen, voraus gesetzt, sie sind Intel kompatibel. ARM (Raspberry) geht nicht, die haben einen anderen Befehlssatz.
  
 
=== Hilfs- Deklarationen und Funktionen ===
 
=== Hilfs- Deklarationen und Funktionen ===

Revision as of 17:23, 25 June 2018

Template:Translate

SSE

Mit der SSE-Erweiterung der Modernen CPUs, kann bis zu 8-9fache Geschwindigkeitssteigerung erzielen, gegenüber klassischen FPU-Operationen.
Am besten werden 4x Vektoren und 4x4 Matrizen unterstützt, dies wird sehr viel bei OpenGL gebraucht.
Dies Assembler-Blöcke sind so angepasst, das sie auf 32Bit und 64Bit CPU laufen, voraus gesetzt, sie sind Intel kompatibel. ARM (Raspberry) geht nicht, die haben einen anderen Befehlssatz.

Hilfs- Deklarationen und Funktionen

type
  TVector4f = array[0..3] of Single;
  TMatrix   = array[0..3] of TVector4f;

procedure WriteVector(v: TVector4f);
begin
  WriteLn(v[0]: 8: 4, '  ', v[1]: 8: 4, '  ', v[2]: 8: 4, '  ', v[3]: 8: 4, '  ');
end;

Die wichtigsten Vektor-Operationen

{$asmmode intel}

procedure TForm1.Button1Click(Sender: TObject);
var
  a: TVector4f = (1, 2, 3, 4);
  b: TVector4f = (5, 6, 7, 8);
  c: TVector4f;

  f: single = 2.0;

begin
  WriteLn('Addieren');
  (*
  c[0] := a[0] + b[0];
  c[1] := a[1] + b[1];
  c[2] := a[2] + b[2];
  c[3] := a[3] + b[3];
  *)
  asm
           Movups  Xmm0, a
           Movups  Xmm1, b
           Addps   Xmm1, Xmm0
           Movups  c, Xmm1
  end;
  WriteVector(c);
  WriteLn();

  WriteLn('Subtrahieren');
  (*
  c[0] := b[0] - a[0];
  c[1] := b[1] - a[1];
  c[2] := b[2] - a[2];
  c[3] := b[3] - a[3];
  *)
  asm
           Movups  Xmm0, a
           Movups  Xmm1, b
           Subps   Xmm1, Xmm0
           Movups  c, Xmm1
  end;
  WriteVector(c);
  WriteLn();


  WriteLn('Multipizieren');
  (*
  c[0] := a[0] * b[0];
  c[1] := a[1] * b[1];
  c[2] := a[2] * b[2];
  c[3] := a[3] * b[3];
  *)
  asm
           Movups  Xmm0, a
           Movups  Xmm1, b
           Mulps   Xmm1, Xmm0
           Movups  c, Xmm1
  end;
  WriteVector(c);
  WriteLn();


  WriteLn('Dividieren');
  (*
  c[0] := b[0] / a[0];
  c[1] := b[1] / a[1];
  c[2] := b[2] / a[2];
  c[3] := b[3] / a[3];
  *)
  asm
           Movups  Xmm0, a
           Movups  Xmm1, b
           Divps   Xmm1, Xmm0
           Movups  c, Xmm1
  end;
  WriteVector(c);
  WriteLn();

  WriteLn('Vertauschen');
  (*
  c[0] := a[3];
  c[1] := a[2];
  c[2] := a[1];
  c[3] := a[0];
  *)
  asm
           Movups  Xmm0, a
           Pshufd  Xmm1,Xmm0, $1b
           Movups  c, Xmm1
  end;
  WriteVector(c);
  WriteLn();

  WriteLn('Alle Multipizieren');
  (*
  c[0] := a[0] * f;
  c[1] := a[1] * f;
  c[2] := a[2] * f;
  c[3] := a[3] * f;
  *)
  f := 2.2;
  asm
           Movss   Xmm0, f
           Pshufd  Xmm0, Xmm0, $00
           Movups  Xmm1, a
           Mulps   Xmm1,Xmm0
           Movups  c, Xmm1
  end;
  WriteVector(c);
  WriteLn();

end;

Vektoren Multiplizieren

{$asmmode intel}

function VectorMultiplySSE(const mat: TMatrix; const vec: TVector4f): TVector4f; assembler;
asm
         Movups Xmm4, [mat + $00]
         Movups Xmm5, [mat + $10]
         Movups Xmm6, [mat + $20]
         Movups Xmm7, [mat + $30]
         Movups Xmm2, [vec]

         // Zeile 0
         Pshufd Xmm0, Xmm2, 00000000b
         Mulps  Xmm0, Xmm4

         // Zeile 1
         Pshufd Xmm1, Xmm2, 01010101b
         Mulps  Xmm1, Xmm5
         Addps  Xmm0, Xmm1

         // Zeile 2
         Pshufd Xmm1, Xmm2, 10101010b
         Mulps  Xmm1, Xmm6
         Addps  Xmm0, Xmm1

         // Zeile 3
         Pshufd Xmm1, Xmm2, 11111111b
         Mulps  Xmm1, Xmm7
         Addps  Xmm0, Xmm1

         Movups [Result], Xmm0
end;

Matrizen multiplizieren

Für eine Matrix-Multiplikation, hat man mit SSE etwa 8-9fache Geschwindigkeitssteigerung, gegenüber klassichen Single-Multiplikationen.

{$asmmode intel}

function MatrixMultiplySSE(const M0, M1: TMatrix): TMatrix; assembler;
asm
         Movups Xmm4, [M0 + $00]
         Movups Xmm5, [M0 + $10]
         Movups Xmm6, [M0 + $20]
         Movups Xmm7, [M0 + $30]

         // Spalte 0
         Movups Xmm2, [M1 + $00]

         Pshufd Xmm0, Xmm2, 00000000b
         Mulps  Xmm0, Xmm4

         Pshufd Xmm1, Xmm2, 01010101b
         Mulps  Xmm1, Xmm5
         Addps  Xmm0, Xmm1

         Pshufd Xmm1, Xmm2, 10101010b
         Mulps  Xmm1, Xmm6
         Addps  Xmm0, Xmm1

         Pshufd Xmm1, Xmm2, 11111111b
         Mulps  Xmm1, Xmm7
         Addps  Xmm0, Xmm1

         Movups [Result + $00], Xmm0

         // Spalte 1
         Movups Xmm2, [M1 + $10]

         Pshufd Xmm0, Xmm2, 00000000b
         Mulps  Xmm0, Xmm4

         Pshufd Xmm1, Xmm2, 01010101b
         Mulps  Xmm1, Xmm5
         Addps  Xmm0, Xmm1

         Pshufd Xmm1, Xmm2, 10101010b
         Mulps  Xmm1, Xmm6
         Addps  Xmm0, Xmm1

         Pshufd Xmm1, Xmm2, 11111111b
         Mulps  Xmm1, Xmm7
         Addps  Xmm0, Xmm1

         Movups   [Result + $10], Xmm0

         // Spalte 2
         Movups  Xmm2, [M1 + $20]

         Pshufd Xmm0, Xmm2, 00000000b
         Mulps  Xmm0, Xmm4

         Pshufd Xmm1, Xmm2, 01010101b
         Mulps  Xmm1, Xmm5
         Addps  Xmm0, Xmm1

         Pshufd Xmm1, Xmm2, 10101010b
         Mulps  Xmm1, Xmm6
         Addps  Xmm0, Xmm1

         Pshufd Xmm1, Xmm2, 11111111b
         Mulps  Xmm1, Xmm7
         Addps  Xmm0, Xmm1

         Movups [Result + $20], Xmm0

         // Spalte 3
         Movups Xmm2, [M1 + $30]

         Pshufd Xmm0, Xmm2, 00000000b
         Mulps  Xmm0, Xmm4

         Pshufd Xmm1, Xmm2, 01010101b
         Mulps  Xmm1, Xmm5
         Addps  Xmm0, Xmm1

         Pshufd Xmm1, Xmm2, 10101010b
         Mulps  Xmm1, Xmm6
         Addps  Xmm0, Xmm1

         Pshufd Xmm1, Xmm2, 11111111b
         Mulps  Xmm1, Xmm7
         Addps  Xmm0, Xmm1

         Movups [Result + $30], Xmm0
end;


Autor: Mathias