Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi schnelstmöglich dividieren? (https://www.delphipraxis.net/160687-schnelstmoeglich-dividieren.html)

Memnarch 26. Mai 2011 09:38

schnelstmöglich dividieren?
 
Tag allerseits, also:

ich habe eine Formel:

Delphi-Quellcode:
Ergebnis := (A*x + B*Y + C*Z) div Wert;
Ergebnis2 := (A*x2 + B*Y2 + C*Z2) div Wert;
Ergebnis3 := (A*x3 + B*Y3 + C*Z3) div Wert;
Da diese formel ca 7 864 320 mal in der Sekunde ausgeführt wird, macht sich der unterschied der ausführungszeiten von + - * / schon ganz schön bemerkbar(1.5GHZ weil 3GHz cpu im Hyperthreading modus >.<, nein kann ich nicht ändern, arbeitsPC).

schön bemerkbar macht sich hier vor allem das DIV. Das zieht ca alleine schon 25%

Hatte mal was mit MMX angefangen, aber ich bin schlichtweg an den dokumentationen verreckt. Hatte da einen schlechten durchblick. Assembler versteh ich zwar soweit, aber MMX und CO war dann(von der dokumentation ausgesehen) dann doch zuviel. Es gab zuviele ecken und kanten für mich an dennen ich scheiterte weil ich nirgends antworten dazu fand >.<.



Hier also mal allgemein gefragt: Wie kann ich obige Kalkulation optimieren? Ergebnis muss leider Integer sein(ja ich weiß von Float nach Integer ist nicht gerade günstig, muss aber sein >.<)


MFG
Memnarch

Phoenix 26. Mai 2011 09:58

AW: schnelstmöglich dividieren?
 
Threaden. Du hast 2 Kerne (wg. Hyperthreading), also nutze auch beide.

Memnarch 26. Mai 2011 10:01

AW: schnelstmöglich dividieren?
 
Das problem war glaub ich das synchronisieren, da war dann alles wieder futsch, vllt auch was falsch gemacht mal gucken.


Genaue erklärung: 30 mal pro sekunden werden pixelbasierte operationen auf eine bitmap angewand. ich hatte es schonmal so gemacht, das je ein Thread eine hälfte des bildes machte, und am ende das ganze in eines gepackt wurde, war aber irgendwie langsamer >.<

MFG
Memnarch

Jumpy 26. Mai 2011 10:10

AW: schnelstmöglich dividieren?
 
Bei / würde das folgende gehen, wodurch AA, BB, CC nur 1 mal berechnet würden. Also nur 3 div.
Da div ja glaub ich was abschneidet funzt das so wahrsch. nicht.
Oder kannst du mit Float rechnen und nur am Ende ein Trunc drauf?

Code:
AA = A div Wert
BB = B div Wert
CC = C div Wert
Ergebnis := (AA*x + BB*Y + CC*Z);
Ergebnis2 := (AA*x2 + BB*Y2 + CC*Z2);
Ergebnis3 := (AA*x3 + BB*Y3 + CC*Z3);

Memnarch 26. Mai 2011 10:15

AW: schnelstmöglich dividieren?
 
ich kann mit float rechnen, aber trunc amt DIV in sachen performance gut nach.

Leider sind bei jedem durchlauf alle werte anders, ich kann mir also über mehrere durchläufe keine werte zurücklegen, das ist mein problem.

JasonDX 26. Mai 2011 10:15

AW: schnelstmöglich dividieren?
 
Die optimale (und wahrscheinlich die einzig performant vertretbar) Lösung ist die GPU. Die ist genau für solche Sachen ausgelegt: Einfache(re) Operationen hundertfach parallel ausführen. Dein Problem sollte von den Einführungsbeispielen, die bei CUDA oder OpenCL dabei sind, gedeckt werden, d.h. der Einlese- und Implementierungsaufwand würde sich durchaus in Grenzen halten.

greetz
Mike

Memnarch 26. Mai 2011 10:23

AW: schnelstmöglich dividieren?
 
@Jason: das hört sich nicht schlecht an, danke :). Fürchte zwar dann kann ich meinen Softwarerasterizer nicht mehr Softwarerasterizer nennen(das ist das eigentliche anwendungsgebiet :twisted: ), aber trotzdem interressant ;). werds mir angucken.

shmia 26. Mai 2011 10:31

AW: schnelstmöglich dividieren?
 
Welche Werte sind denn für "Wert" zu erwarten?
Wieviele Bits sind gesetzt?
Sind nur ein oder zwei Bits gesetzt, dann könnte man mit Rechtsschieben und Addieren arbeiten.
Und dann gäbe es ja auch noch SSE3.

himitsu 26. Mai 2011 10:46

AW: schnelstmöglich dividieren?
 
Welche Werte haben denn die ganzen Variablen so im Durchschnitt, bzw. sind einige davor "fest"?
Eventuell kann man ja die Berechnung selber verändern

Memnarch 27. Mai 2011 09:10

AW: schnelstmöglich dividieren?
 
Das ganze ist wie folgt:

Obiges ist ein MinimalTeil eines Softwarerasterizers den ich geschrieben habe, nämlich die Finale kalkulation der Farbwerte eines Bildpunktes. Dazu müssen die Farbwerte der 3 Vertices interpoliert werden.

Wenn ich ein dreieck ABC habe, und einen Punkt P der dadrin liegt, muss ich die Farbwerte für P ermitteln. Nehmen wir als beispiel den rotkanal:

Alle 3 Vertices haben einen Rotwert, diese 3 Vertices haben aber an verschiedenen punkten einen stärkeren/schwächeren einfluss. Je näher P an einem Vertex ist, desto stärker ist dessen Farbanteil, ansonsten schwächer.

Kalkuliert wird so:

Ich berechne für Vertex A das Dreieck PBC, für B das Dreieck PCA, für C das dreieck PAB. Und dann noch die fläche von ABC. Wenn ich nun eine der vorherigen flächen durch die Fläche ABC teile, bekomme ich den Faktor.

Also z.B PBC/ABC = Factor von Rotwert des Vertex A.

Was ihr am anfang gelesen habt war also:

Delphi-Quellcode:
Rotwert := (FlächeA*RotA + FlächeB*RotB + FlächeC*RotC) div Gesamtfläche;
Wie bereits zu sehen ist ist die kalkulierung des Faktors so rausgekürtzt dass ich pro Farbwert nur einmal dividiere.

Da gabs auch noch was mit Linearer Interpolation übers dreieck(da kann ich die Formel durch kleine additionen ersetzen), aber da bekommt man Floatwerte raus, und die muss ich erst truncaten und dann komm ich zum selben ergebnis >.<.

In dem C++ Rasterizer von dem ich gelernt habe, wurden FixedKommaZahlen verwendet, das war glaub ich um besser von Komma nach Integer zahlen zu kommen. Leider absolut keine Ahnung wie ich das in Delphi umsetzen sollte, da hatte ich ein Paar probleme v.v

MFG
Memnarch

Sir Rufo 27. Mai 2011 09:15

AW: schnelstmöglich dividieren?
 
FixedKomma ist der DatenTyp Currency (der arbeitet intern als Int64)

Memnarch 27. Mai 2011 09:23

AW: schnelstmöglich dividieren?
 
Nur bei Currency bin ich mir icht sicher wie das ergebnis ausschaut. Wenn es sich um einen 64bit integer handelt, wie schnell kann der im vergleich zu einem 32bit integer kalkuliert werden?(P4 hier muhaha^^).

Und den bekomm ich dann z.B per bitshift in einen Integer oder übernimmt das Delphi hier für mich?
Erstmal testen wie schnell das mit dem datentypen hier geht o.O.( er braucht ja immerhin doppelt soviel an registerplatz wie "normale" integer)


MFG
Memnarch

himitsu 27. Mai 2011 09:52

AW: schnelstmöglich dividieren?
 
Int64-Divisionen und Multiplicationen sind sehr langsam, da sie über mehrere 32-Bit Operationen in den 32-Bit-Registern emuliert werden.

siehe Unit System:
Delphi-Quellcode:
{ 64-bit Integer helper routines }
procedure __llmul;
procedure __lldiv;
procedure __lludiv;
procedure __llmod;
procedure __llmulo;
procedure __lldivo;
procedure __llmodo;
procedure __llumod;
procedure __llshl;
procedure __llushr;
Currency wird aber als ein Befehl über die FPU behandelt, wie die normalen Float-Typen auch.
Wenn man Currency nach Int64 castet, dann steht im Int64 natürlich ein 10000 mal größerer Wert drin, wie im Currency.
Leider kann man soeinen "krumen" Wert (auch Sicht des Zweierkomplements) nicht weg-shiften und so "schnell" abrunden.

Eventuell könnte man über die MMX-Register da noch Einiges machen wie z.B. mehrere Berechnungen gleichzeitig durchführen.

Memnarch 27. Mai 2011 09:59

AW: schnelstmöglich dividieren?
 
Mit MMX hab ich zwar mal angefangen, aber nicht alles gefunden was ich brauchte. Ich habe es dann gelassen.

Soll ja für sowas wie geschaffen sein, da ich eine formel 3 mal hintereinander ausführe.
Hatte aber irgendwo seinerzeit probleme damit, ka mehr wo.

Aber am ende muss truncated werden und hier ist einfach alles futsch. da geht garnichts. wenn ich truncate kann ich auch gleich DIV benutzen, es gab da keinen nennenswerten unterschied.


MFG
Memnarch

Medium 27. Mai 2011 11:29

AW: schnelstmöglich dividieren?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Um die Division bzw. alternativ non-integers wirst du vermutlich kaum herum kommen. Eventuell findest du hier (letzte Kategorie) noch ein paar hilfreiche Anregungen.

Eine Idee hätte ich noch: Weg mit den baryzentrischen Koords, und her mit einer Scanline. Dann könnte man "von oben nach unten" durch gehen, und hätte pro Y-Koordinate pro Dreieck zwei lineare Interpolationen, plus einer weiteren für jeden Pixel. Dazu das Bildchen im Anhang. p0 und p1 müssten ja nur je ein mal pro Scanline pro Dreieick ermittelt werden (hat man Adjazentsinfos, kann man benachbarte Strecken gleich weiter benutzen und müsste bis auf beim ersten Mal sogar nur eine Strecke neu interpolieren), und pro Pixel muss dann nur noch zwischen den p0 und p1 linear interpoliert werden.

Memnarch 27. Mai 2011 12:15

AW: schnelstmöglich dividieren?
 
@Medium: Das ist richtig wenn ich nur die Plane zeichnen will(also das rasterisieren), wenn ich aber einen wert der Vertices interpolieren muss(z.B. welchen Z wert hat der punkt P an PosXY wenn die Vertixe ABC die ZWerte SoUndSo haben), reicht es nicht wenn ich nur zwischen den Vertices interpoliere.

Medium 27. Mai 2011 12:48

AW: schnelstmöglich dividieren?
 
Du kannst statt der Farben doch auch einfach die Z-Koordinate da einsetzen :)

Wofür brauchst du die eigentlich?

Memnarch 27. Mai 2011 13:57

AW: schnelstmöglich dividieren?
 
Was? Die farben oder die Z-Koordinaten?

Die Farben werden einfach für den Farbverlauf zwischen den 3 Vertices benutzt. Jeder Vertex hat RGB farbwerte.

Besser als eine einzige Farbe, bis ich nen Texturrasterizer draus gemacht hab^^.


MFG
Memnarch

Medium 27. Mai 2011 14:12

AW: schnelstmöglich dividieren?
 
Ich meinte die Z-Coords :) Gouraud-Shading war klar.

Memnarch 27. Mai 2011 14:14

AW: schnelstmöglich dividieren?
 
Na für die Depthmap ;)
Sonst quadrutschelt es mir ja alles durcheinander ;)(Selbs wenn ich vorher sortieren würde).

Ist dieselbe Technik wie sie auch seit Jahren für alle 3dspiele angewand wird.

Medium 27. Mai 2011 15:04

AW: schnelstmöglich dividieren?
 
Uhlala, nen vollwertiger Z-Puffer in Software ist allerdings happig du. Da kenne ich, als "üblich" Sortierung nach Dreiecksschwerpunkt-Z und Front-to-Back Rendering mit einfachem Stencil. Man kann natürlich Fälle bekommen (bzw. mutwillig erzeugen :) ), bei denen dann mal was komisch wird (das ein oder andere Loch ggf.), aber die Ersparnis in der Verarbeitungszeit ist doch gewaltig dann - verglichen mit dem gerigen Umfang an "glitches" den man sich einhandelt vor allem.
Bei Front-to-Back muss man so allerdings Transparenz etwas spezieller behandeln. Es kann die Sache aber dennoch sehr wert sein finde ich.

Nichtsdestotrotz ließe sich volles Z-Buffering mit o.g. Scanlinemethode wie vorgeschlagen schneller erledigen als mit baryzentrischen bzw. trilinearen Koordinaten, wenn es denn unbedingt sein muss =)

Memnarch 27. Mai 2011 15:25

AW: schnelstmöglich dividieren?
 
Ich nutze FrontToBack rendering + Groben TopLevel ZBuffer + PerPixelZbuffer.

Der grobe Buffer Speichert von einem dreieck an den stellen immer nur den Größt möglichen ZWert des dreiecks, so können andere dreiecken deren kleinster ZWert darunter liegt an diesen stellen gleich verworfen, und der ZWert nicht erst interpoliert werden ;).
Indem ich Die dreiecke in Quadrate unterteile, die die ganz Im Dreieck sind(immer 8*8 pixel), können anhand des ZWerts des quadrats diese stellen vom dreieck halt komplett verworfen werden, was bei meinen scenerien doch schon nen guten schub bietet.(Als Drahtgitter render war gut zu sehen, wie die Gitter anderer objecte hinter vorderen verschwanden, hatte mal zum debuggen nachgeguckt)

Bild ist immoment 512*512 PX groß, die Optimale füllgeschwindigkeit erlaubt im Moment ca 30FPS(GouradShading)

blackfin 27. Mai 2011 15:45

AW: schnelstmöglich dividieren?
 
Eventuell könnte dir vielleicht auch, je nach Komplexität und Polygonanzahl, die Technik des Span-Buffers weiterhelfen...

Namenloser 27. Mai 2011 15:55

AW: schnelstmöglich dividieren?
 
Zunächst mal gucken, ob es bestimmte Werte gibt, die fest sind oder nicht jedes mal neu berechnet werden, wie Jumpy in #4 gesagt hat.

Ansonsten könnte auch SSE interessant sein. Die 128Bit breiten Register von SSE bestehen, wenn ich es richtig verstanden habe, aus 4 32Bit breiten Unterregistern, sind also quasi ein Vierer-Vektor. Operationen werden dann immer für alle Register ausgeführt.

Deine 3 Ergebnisse kannst du ja als Dreier-Vektor auffassen. Was du aktuell machst ist ja folgendes:
Delphi-Quellcode:
Ergebnis[1] := (A*X1 + B*Y1 + C*Z1) div Wert;
Ergebnis[2] := (A*X2 + B*Y2 + C*Z2) div Wert;
Ergebnis[3] := (A*X3 + B*Y3 + C*Z3) div Wert;
Mit SSE könntest du (A*X1 + B*Y1 + C*Z1), (A*X2 + B*Y2 + C*Z2) und (A*X3 + B*Y3 + C*Z3) in einen Vektor packen, und dann alle Divisionen in einem Rutsch ausführen!

Ich habe aber selbst noch nicht mit SSE gearbeitet, daher kann ich es nur oberflächlich beschreiben...

Medium 27. Mai 2011 16:02

AW: schnelstmöglich dividieren?
 
Das heisst, dass dein Wert 7.864.320 op/s für die Ermittlung der Z-Koords nur ein Worst-Case ist gell? Das aber nur am Rande. Nach wie vor bin ich überzeugt, dass diese dual-lineare Interpolation schneller wäre als trilinear (was du jetzt machst).

Ich hatte vor einiger Zeit auch mal einen Artikel zu heaven7 gelesen. Dort wurde mit Hilfe eines Octrees entschieden, ob Punkte tatsächlich getraced werden müssen, oder ob die Szene in dem bereich so simpel ausfällt, dass Interpolation im Screenspace von bereits berechneten Pixeln ausreicht. Das ist zwar ein Raytracer, aber ggf. dennoch eine möglicher weiterverwurstbarer Ansatz zur Optimierung.

Der Span-Buffer ist interessant, riecht aber nach mächtig Overhead. Mag sowas nicht, wenn die Effizienz einer Optimierung je nach Datenlage zur Verschlechterung mutieren könnte :)

Amateurprofi 27. Mai 2011 16:03

AW: schnelstmöglich dividieren?
 
@Memnarch:

Ich würde ja ganz gern mal versuchen eine flinke Funktion zu schreiben, aber leider kann ich deinen Beiträgen nicht entnehmen, welche Variablen-Typen du verwendest.
Also sag mal :
a) Sind das Bytes oder Words oder ... ?
b) Welche minimalen und maximalen Werte können die Variablen A, B, C, x, Y, Z, x2, Y2, Z2, x3, Y3 und Z3 annehmen ?
c) Falls du z.B. Int64 Variablen nimmst, der größte vorkommende Wert aber in ein Word paßt, könntest du dann auf "kleinere" Typen ausweichen ?

Memnarch 27. Mai 2011 16:47

AW: schnelstmöglich dividieren?
 
@AmateurProfi: Flächen ABC und Gesamt sind Integer, in diesem Beispiel waren die XYZ variablen die Farben also Bytes.

Bei den flächen kann ich schlecht auf kleinere größen ausweichen. 512*512/2 liegt soweit ich weiß über Shortint.

Whops glaube ich hab mich verschrieben :P Pro BildAufbau werden 786432 DIVs für die FARBEN gebraucht.
ZWert ist natürlich imo "nur" 262144 pro bildaufbau(eben pro pixel)

Obige DIV werte sind darauf ausgerechnet dass 2 Triangles so vor der Camera hocken, das jeder Pixel bedeckt ist und somit kalkuliert werden muss.

Aber vllt könnte ich pro 8*8 PixelZelle eines dreiecks die 4 ecken wie oben kalkulieren und im Quadrat anders(linear?) interpolieren.....ah mist muss eh wieder truncated werden >.<



MFG
Memnarch

Bjoerk 27. Mai 2011 17:12

AW: schnelstmöglich dividieren?
 
Bist Du Dir mit den 7864320 /s sicher?

Mit Intel Core 2 Q6600 2,4 GHz 2,4 Ghz 250-300 ms (laut GetTickCount).

Delphi-Quellcode:
function J: integer;
begin
  Result:= Random(10000)+1;
end;


procedure TForm1.Button11Click(Sender: TObject);
const
  N = 7864320;
var
  T: cardinal;
  Ergebnis1, Ergebnis2, Ergebnis3,
  Wert,
  A, B, C,
  X1, Y1, Z1,
  X2, Y2, Z2,
  X3, Y3, Z3: integer;
  I: integer;
  S: double;
begin
  A:= J;
  B:= J;
  C:= J;
  X1:= J;
  X2:= J;
  X3:= J;
  Y1:= J;
  Y2:= J;
  Y3:= J;
  Z1:= J;
  Z2:= J;
  Z3:= J;
  Wert:= J;
  S:=0;
  T:= GetTickCount;
  for I:= 1 to N do
  begin
    Ergebnis1:= (A*X1 + B*Y1 + C*Z1) div Wert;
    Ergebnis2:= (A*X2 + B*Y2 + C*Z2) div Wert;
    Ergebnis3:= (A*X3 + B*Y3 + C*Z3) div Wert;
    S:= S+Ergebnis1+Ergebnis2+Ergebnis3; // damit die CodeOptimierung ..
  end;
  ShowMessage (IntToStr(GetTickCount-T));
  ShowMessage (FloatToStr(S)); // .. nicht zuschlägt
end;


procedure TForm1.FormCreate(Sender: TObject);
begin
  Randomize;
end;

Medium 27. Mai 2011 17:15

AW: schnelstmöglich dividieren?
 
Noch ein Stichwort frei in die Runde geschmissen: Multithreading :)
Bringt bei einem P4 wohl nicht die Welt, nur bei aktuellen Quadcores mit HT wär das sicherlich nett.

Amateurprofi 27. Mai 2011 19:29

AW: schnelstmöglich dividieren?
 
@Memnarch:

Ich hab das mal mit der FPU versucht, aber die Ergebnisse sind, gelinde gesagt, ernüchternd (etwa doppelte Rechenzeit vs. simplem Delphi-Code).
Sorry.
Ich hab auch über SSE3 nachgedacht, aber keinen vernünftigen Ansatz gefunden.

Medium 27. Mai 2011 19:37

AW: schnelstmöglich dividieren?
 
Irgendwann ist eben auch Schluss mit Optimierbarkeit auf unterster Ebene - irgendwo MUSS ja auch was berechnet werden :). Daher eben auch unsere Vorschläge, an höhergelegenen Logiken noch was rauszuholen. Wenn es Z sein muss, und zwar per Pixel, wird man um was auch immer für eine Interpolation für jeden Pixel nicht herum kommen, und Interpolation sind Verhältnisrechnungen, und da steckt ja schon fast Sprachlich drin "duuu mussssst dividiiiieren". Oft auch Floatlastig, da gern Ranges von 0..1 genommen sind (wobei man da, wenn es nur linear bleibt, mittels Skalierung auch noch drum rum kommt meistens).
Es bleibt also nur zu gucken, wie man möglichst geschickt interpoliert, oder wie man im Vorfeld noch besser, noch mehr Notwendigkeit zur Interpolation gleich eliminiert. Oder man taucht in Parallelisierung ab (was aber so generell sicherlich sinnvoll ist, egal wie das hier ausgehen wird.)

OldGrumpy 28. Mai 2011 10:42

AW: schnelstmöglich dividieren?
 
@Amateurprofi: Hast Du denn auch die ganzen Constraints bzgl. Alignment usw. beachtet und die Daten optimal arrangiert? Wundert mich etwas, dass es "mit den neueren Opcodes" langsamer sein soll als mit dem "Oldschool" Delphi-Compiler :)

Amateurprofi 28. Mai 2011 11:34

AW: schnelstmöglich dividieren?
 
@OldGrumpy:

Das unten stehende war mein Versuch.

Ausschließlich mit der FPU zu arbeiten hat außer deutlicher Verschlechterung nichts gebracht.
Vielleicht bringt eine gemische Lösung etwas, z.B. alle Multiplikationen und Additionen in den
'normalen' Registern machen und nur die Divisionen mit der FPU.
Ich glaube aber nicht, daß das was bringt. Der, wie du sagst, "Oldschool" Delphi-Compiler schafft es im 31 CPU-Ticks, und das ist für mein Verständnis verdammt flink.

Kannst es ja mal versuchen, ob eine andere Anordnung der Variablen, oder ein anderer Ablauf eine bessere Zeit bringt.

Delphi-Quellcode:
var
   wert,a,b,c,x,y,z,ergebnis,x2,y2,z2,ergebnis2,x3,y3,z3,ergebnis3:integer;

FUNCTION TimeStamp:int64;
asm
   rdtsc
end;

PROCEDURE Test1;
begin
   Ergebnis := (A*x + B*Y + C*Z) div Wert;
   Ergebnis2 := (A*x2 + B*Y2 + C*Z2) div Wert;
   Ergebnis3 := (A*x3 + B*Y3 + C*Z3) div Wert;
end;

PROCEDURE Test2;
asm
   fild  wert
   fild  a
   fild  b
   fild  c
   fild  x
   fmul  st,st(3)
   fild  y
   fmul  st,st(3)
   faddp
   fild  z
   fmul  st,st(2)
   faddp
   fdiv  st,st(4)
   fistp ergebnis
   fild  x2
   fmul  st,st(3)
   fild  y2
   fmul  st,st(3)
   faddp
   fild  z2
   fmul  st,st(2)
   faddp
   fdiv  st,st(4)
   fistp ergebnis2
   fild  x3
   fmulp st(3),st
   fild  y3
   fmulp st(2),st
   fild  z3
   fmulp
   faddp
   faddp
   fdivrp
   fistp ergebnis3
end;

PROCEDURE TestPerformance;
const count=100;
var priorityclass,priority:integer; samask,pamask,tamask:cardinal;
    t0,t1,t2,tts:Int64; i:integer;
begin
   GetProcessAffinityMask(GetCurrentProcess,pamask,samask);
   if pamask=0 then exit;
   tamask:=1;
   while tamask and pamask=0 do tamask:=tamask shl 1;
   SetThreadAffinityMask(GetCurrentThread,tamask);
   priorityclass:=GetPriorityClass(GetCurrentProcess);
   priority:=GetThreadPriority(GetCurrentThread);
   SetPriorityClass(GetCurrentProcess,REALTIME_PRIORITY_CLASS);
   SetThreadPriority(GetCurrentThread,THREAD_PRIORITY_TIME_CRITICAL);
   // Etwas einheizen
   for i:=1 to 100000000 do;
   // Feststellen wieviel Ticks TimeStamp braucht
   tts:=High(int64);
   for i:=1 to count do begin
      t0:=TimeStamp;
      t0:=TimeStamp-t0;
      if t0<tts then tts:=t0;
   end;
   // Ticks für Routine 1
   t1:=High(int64);
   for i:=1 to count do begin
      t0:=TimeStamp;
      Test1;
      t0:=TimeStamp-t0;
      if t0<t1 then t1:=t0;
   end;
   dec(t1,tts); // Zeit für TimeStamp abziehen
   // Ticks für Routine 2
   t2:=High(int64);
   for i:=1 to count do begin
      t0:=TimeStamp;
      Test2;
      t0:=TimeStamp-t0;
      if t0<t2 then t2:=t0;
   end;
   dec(t2,tts); // Zeit für TimeStamp abziehen
   SetThreadPriority(GetCurrentThread,priority);
   SetPriorityClass(GetCurrentProcess,priorityclass);
   SetThreadAffinityMask(GetCurrentThread,pamask);
   ShowMessage(IntToStr(t1)+' '+IntToStr(t2)+' '+IntToStr(t1-t2));
end;

PROCEDURE TMain.Test;
begin
   a:=12345;
   b:=23456;
   c:=34567;
   x:=12;
   y:=13;
   z:=14;
   x2:=123;
   y2:=123;
   z2:=125;
   x3:=234;
   y3:=235;
   z3:=236;
   wert:=37;
   testperformance;
end;

Memnarch 28. Mai 2011 17:47

AW: schnelstmöglich dividieren?
 
@Bjoerk: Dir ist schon klar, dass ich mein momentanes Programm auf nem P4 3GHZ im MT Modus ausführe?(Somit nur 1.5GHz wegen virtuellem kern). :)

@Amateurprofi:
Habe schonmal nen Mix versucht, das Resultat war auch ernüchtenrd. Da die CPU immerwieder in die FPU wechseln muss, nimtm schonalleine diese umstellung in meinder anwendung mehr weg als wenn ich einfach nur stumpf dividieren würde.

blackfin 28. Mai 2011 17:59

AW: schnelstmöglich dividieren?
 
Auch wenn ich nicht nicht mehr wirklich mitreden kann, will ich dir mal meinen Respekt zollen :-D
Einen Software-Renderer / Rasterizer zu schreiben ist einfach...geil! :-D
Gib nicht auf!
....
..
..
(vielleicht hilft das ja auch etwas zur Motivation im ganzen Performance-Frust :-D)

bit4bit 29. Mai 2011 23:02

AW: schnelstmöglich dividieren?
 
@Memnarch

Versuch doch mal folgende Idee (nicht getestet) :

Delphi-Quellcode:
PROCEDURE Test1;
var Wert2 : Integer;
begin
   Wert2 := Integer((2 shl 32) div Wert);
   Ergebnis := Integer(((A*x + B*Y + C*Z) * Wert2) shr 32);
   Ergebnis2 := Integer(((A*x2 + B*Y2 + C*Z2) * Wert2) shr 32);
   Ergebnis3 := Integer(((A*x3 + B*Y3 + C*Z3) * Wert2) shr 32);
end;
Normalerweise müsste der Compiler das gut optimieren können.

Wenn nicht, hilft Assembler. Da das Ergebnis in 2 Bytes passt,
kannst Du nach der Multiplikation einfach den Inhalt von DX benutzen.

MfG

bit4bit

Amateurprofi 30. Mai 2011 02:07

AW: schnelstmöglich dividieren?
 
@bit4bit;

Delphi-Quellcode:
PROCEDURE Test1;
var Wert2 : Integer;
begin
   Wert2 := Integer((2 shl 32) div Wert);
   Ergebnis := Integer(((A*x + B*Y + C*Z) * Wert2) shr 32);
   Ergebnis2 := Integer(((A*x2 + B*Y2 + C*Z2) * Wert2) shr 32);
   Ergebnis3 := Integer(((A*x3 + B*Y3 + C*Z3) * Wert2) shr 32);
end;
Und welche Ergebnisse erwartest du ?
Zur ersten Zeile "Wert2 := Integer((2 shl 32) div Wert);" :
2 shl 32 ergibt 2, weil um 32 mod 32 (=0) Bits verschoben wird.
Also wird Wert2 in der Regel 0 sein und damit werden auch die Ergebnisse alle = 0 sein.

Memnarch 30. Mai 2011 08:17

AW: schnelstmöglich dividieren?
 
@Blackfin: Danke^^.
Allerdings weniger zeit im Moment dran weiterzuarbeiten. Sourcecode auf der Arbeit geschrieben, und wenn ich dran weitermachen will muss ichs im moment zuhause machen...dafür muss ich dan nochmal alles schreiben XD.(da hab ich dan aber auch nen Dualcore mit 2.66GHZ pro REALEM Kern :twisted: )

Wenn es mal interressiert:

http://www.devmaster.net/forums/showthread.php?t=1884

Dieser Artikel hat mir sehr geholfen. Konnte am anfang vllt 4 Bilder pro sekunde anzeigen. Obiger Artikel hat mir gut verdeutlicht wie man soetwas optimieren kann. Bein aktueller Softwarerasterizer basiert auch auf obigem + Einigen anderen sachen wie z.B. depthbuffer etc.(texturemapping geht übrigens auch schon...wenn auch etwas...meh im aussehen^^)

@Amateurprofi: hat das beispiel überhaupt nen sinn? ansonsten hätt ichs mit nem shift wert um einiges kleiner als 32 probiert...o.O

EDIT: bin auch im Moment zuhause sehr beschäftigt...mit ner Art PreCompiler :D Thread auf 3DGamestudio.de

MFG
Memnarch

Delphianer 30. Mai 2011 09:11

AW: schnelstmöglich dividieren?
 
Hallo,

wenn Du Geschwindigkeit auf Kosten der Genauigkeit steigern kannst/willst, hätte ich auch noch einen Vorschlag.
Du könntest die Ergebnisse der Division in einem Array abspeichern, z.B. 4096 x 4096. Das hieße aber, dass Du Deine Werte für Divisor und Dividend auf 4096 Werte eindampfen müsstest. Das Array ließe sich sicher auch noch in Maßen vergrößern. Wenn die Genauigkeit ausreicht, bist Du mit einem Array-Zugriff rasend schnell.

Viele Grüße,

Lutz

Memnarch 30. Mai 2011 09:26

AW: schnelstmöglich dividieren?
 
Ah, sone art lookup table? Sowas nutz ich schon für die COS/SIN funktionen^^.

Nur wie soll ich die einrichten?
Wenn die formel X/Y ist dan sowas wie:


Ergebnis := Tabelle[x][y];

oder wie?
Von der genauigkeit könnte es reichen weil der finale schritt der division immer für die Pixelkoordinaten also Integer ist. Aber wie soll ich die aufbauen?

EDIT: vergiss es, das haut sich automatisch in die Fritten, den die Fläche eines Dreiecks kann auch width*Height des bildschirms sein, dann ist sowieso schluss >.<


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:23 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz