AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

[ASM / SSE] Vektoroperationen

Ein Thema von Edlmann · begonnen am 13. Jun 2012 · letzter Beitrag vom 18. Jun 2012
 
Edlmann

Registriert seit: 19. Nov 2010
212 Beiträge
 
#1

[ASM / SSE] Vektoroperationen

  Alt 13. Jun 2012, 18:37
Nachmittag DPLer,

ich habe mich heute mal daran Gesetz, die SIMD-Extensions ein wenig genauer unter die Lupe zu nehmen,
speziell wie man diese zur Berechnung von Vektoren einsetzen kann. Ich hab dafür ein paar kleine Testroutinen gebastelt,
und hätte 2 Fragen:
1. Wo liegt noch Optimierungspotential?
2. Warum ist die normale Addition gegenüber der SSE-Single-Vector Addition nur minimal schneller?

(Messwerte für 2 Millionen Verticies operationen, einmal addieren je 2er Vektoren, 1x Multiplizieren:
Ganz normaler Delphi-Code: im Schnitt 109.000 Zykel
SSE-Single-Vector: im Schnitt 102.000 Zykel
Addieren ganzer Arrays: 62.736).

Zum Quelltext dahinter:
Die Vektoren sind als einfache Records spezifiziert

Delphi-Quellcode:
const
  ALENGTH = 2000000;

type
  TTestVec = packed record
    x, y, z, w: Single;
  end;

...

  Vecs1: array[0..ALENGTH] of TTestVec;
  Vecs2: array[0..ALENGTH] of TTestVec;
  ResVecs: array[0..ALENGTH] of TTestVec;

Und die Methoden(hier mal nur die zum Addieren, die zum Multiplizieren dementsprechend statt + / ADDPS mit * / MULPS)

Standard Delphi:
Delphi-Quellcode:
function AddVecs(const av1, av2: TTestVec): TTestVec;
begin
  Result.x := av1.x + av2.x;
  Result.y := av1.y + av2.y;
  Result.z := av1.z + av2.z;
  Result.w := av1.w + av2.w;
end;
Single-Vector-SSE:
Delphi-Quellcode:
function AddVecsSSE(const av1, av2: TTestVec): TTestVec;
var p1, p2: Pointer;
begin
  p1 := @av1.x;
  p2 := @av2.x;
  asm
    MOV ECX, p1
    MOV EDX, p2

    MOVUPS XMM0, [ECX]
    MOVUPS XMM1, [EDX]

    ADDPS XMM0, XMM1
    MOV ECX, @Result.x
    MOVUPS [ECX], XMM0
  end;
end;
und schließlich Array-SSE-Addieren:
Delphi-Quellcode:
procedure AddVecsArraySSE(const av1, av2: Pointer; const outarray: Pointer; const Length: Integer; const Strafing: Integer);
begin
  asm
    //ECX = 1st Array
    //EDX = 2nd Array
    //EBX = Length of the Array
    //EAX = Pointer to the outarray
    MOV ECX, av1
    MOV EDX, av2
    MOV EBX, Length
    MOV EAX, outarray

    @@LoopLabel:
    MOVUPS XMM0, [ECX]
    MOVUPS XMM1, [EDX]

    ADDPS XMM0, XMM1
    MOVUPS [EAX], XMM0
    //Die Pointer um Strafing verschieben
    ADD ECX, Strafing
    ADD EDX, Strafing
    ADD EAX, Strafing
    DEC EBX
    //Sind wir mit der Länbe bei -1, haben wir unser Array durch
    CMP EBX, -1
    JNE @@LoopLabel
  end;
end;


Und Aufgerufen wird der Spass mit:

Delphi-Quellcode:
for x := 0 to ALENGTH do
begin
  ResVecs[x] := AddVecs(Vecs1[x], Vecs2[x]);
end;

for x := 0 to ALENGTH do
begin
  ResVecs[x] := AddVecsSSE(Vecs1[x], Vecs2[x]);
end;

AddVecsArraySSE(@Vecs1[0].x, @Vecs2[0].x, @ResVecs[0].x, ALENGTH, 16);
Vielen Dank schonmal,
Edlmann

P.S. Ist nur ne Testimplementation, um zu schauen wie groß der Performancegewinn ist.

Geändert von Edlmann (13. Jun 2012 um 18:45 Uhr)
  Mit Zitat antworten Zitat
 


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:24 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz