Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Dyn. Array Teilmenge schnell kopieren (https://www.delphipraxis.net/160012-dyn-array-teilmenge-schnell-kopieren.html)

Satty67 22. Apr 2011 21:06

Dyn. Array Teilmenge schnell kopieren
 
Hallo,

ich muss einen Abschnitt eines Dynamischen Arrays in ein zweites Array kopieren. (Hab' mich entschlossen, endlich mal MergeSort zu verstehen und umzusetzen... läuft inzwischen auch)

Symbolischer Codeausschnitt:
Delphi-Quellcode:
type
  TPointerArray = array of Pointer;
var
  Base, Part : TPointerArray;
  i, offset, count : Integer;
begin
  // alles initialisiert (SetLength etc.) und
  // offset/count berechnet

  for i := 0 to Count-1 do
    Part[i] := Base[offset + i];
Funktioniert auch, nur wollte ich es beschleunigen (mit Move).
Die For-Schleife ist wie folgt ersetzt:
Delphi-Quellcode:
  Move(Base[offset], Part[0], count);
.
Mir füllt es aber das Part-Array mit lauter Nullen, statt mit den realen Werten.

Ich komme nicht drauf, was schief läuft.

Alternativ nehme ich auch einen anderen Vorschlag, wie ich die Kopieraktion in der For-Schleife beschleunigen kann.

Bummi 22. Apr 2011 22:31

AW: Dyn. Array Teilmenge schnell kopieren
 
wenn ich das im Debugger anschaue sieht alles so aus wie ich es erwarten würde...
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
   Base, Part : TPointerArray;
begin
  Setlength(Base,100);
  Setlength(Part,100);
  Base[10] := self;
  Base[11] := self; Base[12] := self; Base[13] := self;
  Move(Base[10],Part[0],5*SizeOf(Pointer));

end;

Satty67 22. Apr 2011 23:11

AW: Dyn. Array Teilmenge schnell kopieren
 
Danke!

Dein Post hat geholfen die Tomaten von den Augen zu bekommen ;)

Count muss beim Move natürlich mit SizeOf(Pointer) multipliziert werden :oops:

Delphi-Quellcode:
Move(Base[offset], Part[0], count * SizeOf(Pointer));
.

Move spart nochmal 7% Zeit beim Gesamtergebnis

Medium 23. Apr 2011 00:14

AW: Dyn. Array Teilmenge schnell kopieren
 
Was mich allerdings grad etwas wundert, weil Move() intern doch auch nur über eine Schleife kopiert - und zwar byteweise! Sollte es nicht eigentlich schneller sein, die vollen 32 Bit der Pointer am Stück zu schubsen? :gruebel:

Aha okay, grad inne Soße geschaut. Move() kopiert, ab >32 zu verschiebenden Bytes, Quadwords. Und zwar in ASM, d.h. die Bereichsprüfung dürfte ebenfalls umgangen sein. Gut, ich drück trotzdem mal auf "Antworten", einfach um für mich nochmals zu dokumentieren, dass nochmal Nachsehen keine soooo schlechte Sache ist :mrgreen:

himitsu 23. Apr 2011 00:23

AW: Dyn. Array Teilmenge schnell kopieren
 
Nur daß bei der Schleife im Move die Adressierunfg nicht ständig zweimal, je Wert, neu berechnet wird.
Das wird nur einmal und dann wird nur noch weitergezählt.

PS: Seit Delphi 2006/2007, also seit das FastCodeProjekt im Delphi aufgenmmen wurde, ist dieses Move soweit optimiert, daß dort sogar MMX-Register genutzt werden können (je bis zu 8 Byte pro Schleifendurchlauf)

Medium 23. Apr 2011 00:41

AW: Dyn. Array Teilmenge schnell kopieren
 
QWords eben, jup, stimmt. Und aha! Ich hatte noch das Move von D7 im Hinterkopf, und da vermutlich auch nur den Pascal-Fallback, da ich damals noch zu wenig ASM konnte um das zu kapieren :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:33 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-2025 by Thomas Breitkreuz