Autor Beitrag
Bryce
Hält's aus hier
Beiträge: 6



BeitragVerfasst: Mi 19.02.03 17:10 
Ich arbeite gerade mit ein paar Freunden an einem Jump 'n Run Spiel. Wir haben uns überlegt mal was in TMT Pascal zu probieren, ich hoffe aber trotzdem, dass ihr uns helfen könnt, da ich die Routine nähmlich später auch für Delphi-Projekte verwenden möchte. Die Kopierroutine, die unsere Sprites in den Bildschirmspeicher kopiert ist allerdings noch verbesserungswürdig.

Ich suche eine Routine, die Daten möglichst schnell von einer Speicherposition zu einer anderen kopiert, also praktisch eine optimierte Version der Move-Prozedur aus Pascal. Ich hatte schon mal an einem anderen Board nach so etwas gefragt und mir wurde da unter anderem eine MMX-Version angeboten, die allerdings mit MMX nicht so viel zu tun haben kann, da sie sogar unter BP7 lief, wo ja nichtmal 386 Code übersetzt werden kann. Ich würde mich daher freuen, wenn mir jemand sagt wie man eine solche Kopierroutine durch MMX oder SSE oder so optimieren kann. Ich kenn mich in dem Gebiet leider überhaupt nicht aus.

cu,
Bryce
OregonGhost
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 215



BeitragVerfasst: Mi 19.02.03 18:54 
Ich behaupte jetzt einfach mal, dass du Zugriffe auf den Speicher durch MMX, SSE oder 3DNow! nicht schneller machen kannst, weil diese Befehle dafür gedacht sind, eine Operation gleichzeitig auf mehreren Variablen durchzuführen. Dazu müssen diese aber schon in einem entsprechenden Register liegen.

Die Angaben sind aber ohne Gewähr, weil das eigentlich nicht mein Gebiet ist.

_________________
Oregon Ghost
---
Wenn NULL besonders groß ist, ist es fast schon wie ein bisschen eins.
AndyB
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: Mi 19.02.03 19:14 
Man kann das Kopieren z.B. dadurch optimieren dass die Startaddresse durch 4 (für die nähere Zukunft: 8 bzw. 16) teilbar ist. Die beschleunigt, da die CPU nicht 2x auf den Speicher zugreifen muss wenn 32Bit angefordert werden.
Des weiteren kommt es auf die Datenmenge an. Ist diese ebenfalls durch 4 Teilbar, so kann in "einem Zug" alles kopiert werden.
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
procedure MoveLong(const Source; var Dest; LongCount: Cardinal); register; assembler;
asm
 // in: eax <-> Offset Source
 //      edx <-> Offset Dest
 //      ecx <-> [LongCount]
  push esi   // Register sichern
  push edi   // Register sichern
  mov esi, eax   // esi mit der Addresse von Source laden
  mov edi, edx   // edi mit der Addresse von Dest laden
  cld  // Richtung in die "movsd" geht
  rep movsd // LongCount x 4 Bytes kopieren
  pop edi   // Register wiederherstellen
  pop esi   // Register wiederherstellen
end;

Der Code funktioniert nur unter Delphi.

_________________
Ist Zeit wirklich Geld?
OregonGhost
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 215



BeitragVerfasst: Do 20.02.03 14:22 
Da hab ich zwei Sachen zu zu sagen:
1. Visual C++ hat 8-Byte-Ausrichtung ohnehin standardmäßig eingestellt im Hinblick auf Win64. Daher ist das wahrscheinlich auch jetzt schon zu empfehlen, schließlich ist Visual C++ von Microsoft, für deren Betriebssysteme wir ja alle schreiben, und eine 4-Byte-Ausrichtung ist damit ebenfalls gegeben.
2. Im Forum auf c-plusplus.de gab es dazu eine Diskussion ("Optimierungen noch heute gültig?"). Deren Ergebnis stark verkürzt:

  1. Die CPU liest immer mindestens 4 Byte (8 Byte bei 64-Bit-CPUs), daher ist das die Minimalgröße.
  2. 32 Byte ist eine Cacheline, d.h. es werden immer mindestens 32 Byte in den Cache geladen.
  3. 4096 Byte ist eine Seite, die das Betriebssystem verwaltet (Auslagerung etc.), bei größeren Datenmengen kann also auch hierfür optimiert werden.

_________________
Oregon Ghost
---
Wenn NULL besonders groß ist, ist es fast schon wie ein bisschen eins.