Delphi-Quellcode:
type
TTestVec =
packed record
x, y, z, w: Single;
end;
TTestVecArr =
array[0..0]
of TTestVec;
PTestVecArr = ^TTestVecArr;
procedure AddVecsArraySSE(av1, av2: Pointer; outarray: Pointer; Count: Integer);
{$IF SizeOf(Pointer) = 4} // {$IFDEF Win32}
//asm
// MOV EDI, ECX
// MOV ECX, [EBP+8]
// DEC ECX
// CMP ECX, 0
// JL @@exit
// @@loop:
// MOVUPS XMM0, DQWORD PTR [EAX + ECX * 16]
// MOVUPS XMM1, DQWORD PTR [EDX + ECX * 16]
// ADDPS XMM0, XMM1
// MOVUPS DQWORD PTR [EDI + ECX * 16], XMM0
// DEC ECX
// ZGE @@loop
// @@exit:
//end;
asm
MOV EDI, ECX
MOV ECX, [EBP+8]
CMP ECX, 0
JLE @@exit
DEC ECX
CMP ECX, $07FFFFFF
JG @@exit
SHL ECX, 4
@@loop:
MOVUPS XMM0, DQWORD PTR [EAX + ECX]
MOVUPS XMM1, DQWORD PTR [EDX + ECX]
ADDPS XMM0, XMM1
MOVUPS DQWORD PTR [EDI + ECX], XMM0
SUB ECX, 16
JNZ @@loop
@@exit:
end;
{$ELSE}
//type
// TSingleArr = array[0..0] of Single;
// PSingleArr = TSingleArr;
//var
// i: Integer;
//begin
// for i := (Count * 4) - 1 downto 0 do
// PSingleArr(outarray)[i] := PSingleArr(av1)[i] + PSingleArr(av2)[i];
//end;
var
i: Integer;
begin
for i := Count-1
downto 0
do begin
PTestVecArr(outarray)[i].x := PTestVecArr(av1)[i].x + PTestVecArr(av2)[i].x;
PTestVecArr(outarray)[i].y := PTestVecArr(av1)[i].y + PTestVecArr(av2)[i].y;
PTestVecArr(outarray)[i].z := PTestVecArr(av1)[i].z + PTestVecArr(av2)[i].z;
PTestVecArr(outarray)[i].w := PTestVecArr(av1)[i].w + PTestVecArr(av2)[i].w;
end;
end;
{$IFEND}
Keine Ahnung, ob's richtig ist.
Und Schade, daß *16 scheinbar vergessen wurde zu implementieren.
*2, *4 und *8 gibt es ja auch und daß bei der Größe der MMX-Register
Length ist ein unpraktischer Name.
[edit]
Code siehe: Zitat-Funktion ... die Funktion des Delphi-Tags ist immernoch einfach nur schrecklich