Code: Alles auswählen
function MatrixMultiplySSE(const M0, M1: Tmat4x4): Tmat4x4; assembler; nostackframe; register;
asm
Movups Xmm4, [M0 + $00]
Movups Xmm5, [M0 + $10]
Movups Xmm6, [M0 + $20]
Movups Xmm7, [M0 + $30]
Xor Ecx, Ecx
@loop:
Movss Xmm0, [M1 + $00 + Ecx]
Shufps Xmm0, Xmm0, 00000000b
Mulps Xmm0, Xmm4
Movss Xmm2, [M1 + $04 + Ecx]
Shufps Xmm2, Xmm2, 00000000b
Mulps Xmm2, Xmm5
Addps Xmm0, Xmm2
Movss Xmm2, [M1 + $08 + Ecx]
Shufps Xmm2, Xmm2, 00000000b
Mulps Xmm2, Xmm6
Addps Xmm0, Xmm2
Movss Xmm2, [M1 + $0C + Ecx]
Shufps Xmm2, Xmm2, 00000000b
Mulps Xmm2, Xmm7
Addps Xmm0, Xmm2
Movups [Result + Ecx], Xmm0
Add Ecx, $10
Cmp Ecx, $30
Jbe @loop
end;
operator * (const M0, M1: Tmat4x4) Res: Tmat4x4; assembler; nostackframe; register;
asm
Movups Xmm4, [M0 + $00]
Movups Xmm5, [M0 + $10]
Movups Xmm6, [M0 + $20]
Movups Xmm7, [M0 + $30]
Xor Ecx, Ecx
@loop:
Movss Xmm0, [M1 + $00 + Ecx]
Shufps Xmm0, Xmm0, 00000000b
Mulps Xmm0, Xmm4
Movss Xmm2, [M1 + $04 + Ecx]
Shufps Xmm2, Xmm2, 00000000b
Mulps Xmm2, Xmm5
Addps Xmm0, Xmm2
Movss Xmm2, [M1 + $08 + Ecx]
Shufps Xmm2, Xmm2, 00000000b
Mulps Xmm2, Xmm6
Addps Xmm0, Xmm2
Movss Xmm2, [M1 + $0C + Ecx]
Shufps Xmm2, Xmm2, 00000000b
Mulps Xmm2, Xmm7
Addps Xmm0, Xmm2
Movups [Res + Ecx], Xmm0
Add Ecx, $10
Cmp Ecx, $30
Jbe @loop
end;
Code: Alles auswählen
procedure TForm1.Button4x4Click(Sender: TObject);
var
x, y, i: integer;
ma, mb, mc, m0, m1: Tmat4x4;
t: TTime;
const
site = 20000001;
procedure Ausgabe(m: Tmat4x4);
var
i: integer;
begin
for i := 0 to 3 do begin
WriteLn(m[i, 0]: 4: 2, ' ', m[i, 1]: 4: 2, ' ', m[i, 2]: 4: 2, ' ', m[i, 3]: 4: 2);
end;
WriteLn();
end;
function GetZeit(z: TTime): string;
begin
str(z * 24 * 60 * 60: 10: 4, Result);
end;
begin // Den beiden Quellmatrizen Werte zuweisen.
for x := 0 to 3 do begin
for y := 0 to 3 do begin
m0[x, y] := x + y * 4;
m1[x, y] := y + x * 4;
end;
end;
t := now;
for i := 0 to site do begin
ma := m0 * m1; // Operator
end;
WriteLn('Operator SSE: ', GetZeit(now - t));
Ausgabe(ma);
t := now;
for i := 0 to site do begin
mc := MatrixMultiplySSE(m0, m1); // Funktion
end;
WriteLn('SSE neu: ', GetZeit(now - t));
Ausgabe(mc);
end;
Ist dies etwa Zufall ?
Ich habe es mehrmals probiert.