Delphi-PRAXiS
Seite 2 von 2     12   

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 30. Mai 2011 11:46

AW: schnelstmöglich dividieren?
 
Ich nochmal:
Also im Moment ist es ja so, dass ich bei jedem Pixel dividieren muss. Allerdings werkelt da noch so einiges nebenher, womit das nicht die einzigen operationen wären.

Stellen wir uns mal vor, ich dividiere nicht im rasterizer, sondern speicher im Rasterizer nur pro pixel die werte für die Formeln ab. Wenn der rasterizer durchgelaufen ist, gehe ich durch diesen FormelBuffer und kalkuliere dann erst die Farbwerte der pixel. Einerseits kann ich dann ungestört alle Berechnungen direkt hintereinander ausführen(mh...-> optimierung hier vllt besser möglich weil ich nicht mehr switchen muss?) andererseits werden mehrfach berechnungen der farben pro pixel absolut verhindert(kommt hier noch nicht zum tragen, aber bei komplexeren umgebungen). Eine formel kann im schlimmsten fall mehrfach überschrieben werden, aber der finalstep kalkuliert erst.

Jemand noch Ideen?


MFG
Memnarch

Amateurprofi 30. Mai 2011 13:29

AW: schnelstmöglich dividieren?
 
Zitat:

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

Ich vermute bit4bit wollte sowas ähnliches machen wie mit 1/Wert zu multiplizieren, statt durch wert zu dividieren. So wie es da steht funktioniert das offensichtlich nicht,

Vielleicht könnte bit4bit mal erläutern was er sich dabei gedacht hat.

Memnarch 30. Mai 2011 14:08

AW: schnelstmöglich dividieren?
 
oh klasse 1/wert zu multiplizieren wär super...dan hab ich wieder ne float und müsste truncaten >.<

Amateurprofi 30. Mai 2011 14:27

AW: schnelstmöglich dividieren?
 
na ja, bit4bit's idee war sicherlich, das nicht auf Float-Basis zu machen sondern bei Integer-Werten zu bleiben.
Warten wir doch mal seine Erklärung ab, wie er sich das gedacht hat.
Vielleicht funktioniert das ja irdenwie.
Ich hab mich mit dieser speziellen Thematik bisher noch nicht beschäftigt und kann keine fundierte Aussage machen ob das prinzipiell möglich ist oder nicht.
Schneller wäre diese Version vermutlich.

Memnarch 30. Mai 2011 14:35

AW: schnelstmöglich dividieren?
 
Wenn dass wirklich das ist was bit4bit's Idee war, und das funktioniert, bin ich dochmal gespannt.

gammatester 30. Mai 2011 14:43

AW: schnelstmöglich dividieren?
 
Eine Frage, die bisher unbeantwortet ist: Wie oft ändert die der Divisions-Wert und in welchem Bereich liegt er? Zu Division via inverser Multiplkation gibt's seit ewigen Zeiten Beispiele: http://www.cs.uiowa.edu/~jones/bcd/divide.html oder http://www.azillionmonkeys.com/qed/adiv.html
und viele andere. Wenn Wert lokal-konstant ist, oder nur einen relativ kleinen Bereich umfaßt, kann man die Inversen vorberechnen bzw in die Routinen packen, die Wert berechnen (brauchst Du den überhaupt zu was anderen als zum Dividieren?).

Memnarch 30. Mai 2011 15:04

AW: schnelstmöglich dividieren?
 
Wert ändert sich pro Triangle, nicht voraussehbar da sich umgebung/triangles verändern.

Gerade mal getestet:

bit4bit's methode funktioniert SO:

Delphi-Quellcode:
 Wert2 := Integer((2 shl 12) div Wert);
   Ergebnis := Integer(((A*x + B*Y + C*Z) * Wert2) shr 13);
   Ergebnis2 := Integer(((A*x2 + B*Y2 + C*Z2) * Wert2) shr 13);
   Ergebnis3 := Integer(((A*x3 + B*Y3 + C*Z3) * Wert2) shr 13);[/U]
Dem gegenüüber die 'alte' methode:

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;
Wenn ich beides Jeweils 100Millionen mal ausführe (wert2 natürlich nur einmal kalkuliert)
Stellt sich heraus, beides ergibt dasselbe ergebnis, Bit4Bits methode ist aber 4mal SCHNELLER. Seine methode braucht ca 1Sec. Meine 4Sec.

gammatester 30. Mai 2011 15:17

AW: schnelstmöglich dividieren?
 
Wenn Du die Shifts so anpaßt, daß shr 13 zu shr 32 würde und mit Inline-ASM arbeitest, dann kannst Du Dir die Shifts sparen, denn das Ergebnis steht in EDX (und das ganze wäre wohl noch etwas genauer).

Memnarch 30. Mai 2011 15:44

AW: schnelstmöglich dividieren?
 
@gammatester: ich soll shr auf 32 ändern? bit4bit's beispiel mit shr/shl 32 klappt nicht, da komtm immer 0 raus.

Könntest du mir es bitte etwas genauer erklären was du meinst o.O?

EDIT: mal ganz abgesehen davon hab ich gerade ein problem: Ergebnis ist ein Byte wert(farbe eben), und wnen ich nen hardcast Integer reinpacke gibts zwar keine fehler....aber alle farbwerte immer schwarz :stupid:

Amateurprofi 30. Mai 2011 15:47

AW: schnelstmöglich dividieren?
 
Das ist bei mir ganz anders.

Bei 100 Mio Durchläufen braucht (bei mir) die "alte" 1125 ms, die "neue" 843 ms, wobei auch bei mir Wert2 nur einmal berechnet wird.

Auch die Ergebnisse sind nicht identisch.
Bei den Werten, die ich in einem früheren Beitrag eingesetzt habe erhalte ich folgende Ergebnisse

"alte" 25324 235794 447532
"neue" 25278 235362 446713

Ich kann allerdings nicht beurteilen, diese eher geringfügigen Differenzen tolerierbar sind.

Memnarch 30. Mai 2011 15:51

AW: schnelstmöglich dividieren?
 
ACH MIST,
ja lag daran dass ich zu kleine werte eingegeben hatte. Je größer die werte sind, umso ungenauer wird es >.<.

€dit: Zeitlich aber weiterhin dasselbe.

gammatester 30. Mai 2011 15:59

AW: schnelstmöglich dividieren?
 
Hier ein Beispiel (Anzeigewert ist jeweils 12345):
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  res,test, wert, iwert: longint;
begin
  wert := 10000;
  iwert := (int64(1) shl 32) div wert;
  test := 123456789;
  ShowMessage('Div: '+inttostr(test div wert));
  asm
    mov eax,[test]
    mul [iwert]
    mov [res],edx
  end;
  ShowMessage('Mul: '+inttostr(res));
end;

Memnarch 30. Mai 2011 16:23

AW: schnelstmöglich dividieren?
 
WOW klasse.
Mit dieser Methode ist meine spitzen fps von 28-30 auf 52(!!) gestiegen. Ich wusste doch dass die divs und die float/int das waren. Klasse :).

MFG
Memnarch

Amateurprofi 30. Mai 2011 22:58

AW: schnelstmöglich dividieren?
 
@gammatester:
Funktioniert einwandfrei. Mal wieder was dazugelernt.

bit4bit 31. Mai 2011 00:13

AW: schnelstmöglich dividieren?
 
Sorry, da hatte ich einen Flüchtigkeitsfehler drin. :oops:

Delphi-Quellcode:
PROCEDURE Test1;
var Wert2 : Integer;
begin
   Wert2 := Integer((Int64(1) shl 32) div Wert); { <<<------ war falsch }
   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;
Ich benutze einfach nur die Nachkommastellen einer Binärzahl, die 32 bit vor,
und 32 bit nach dem Komma hat. Also 2^32 entspricht der 1 ( =2^0 ).
Wenn ich 2^32 div Wert rechne, hab ich vor dem gedachten Binärkomma immer 0
stehen (Jedenfalls bei den Werten, die hier infrage kommen).
Ich benutze also zur Multiplikation immer nur die 32 bit nach dem Binärkomma
und weiß, dass mein Ergebnis um den Faktor 2^32 zu hoch ist.
Durch die Verwendung von EDX nach der Multiplikation kann ich mir ein "shr 32"
sparen.

Das Ganze würde natürlich auch mit 2^16 klappen, das Ergebnis kann ja nur 8 bit
haben! Wäre aber nur mit 16 bit Arithmetik praktisch. Das Ergebniss wär dann
eben in DX .

@gammatester

Meine Idee ist im Prinzip so, wie du sie umgesetzt hast. Wenn jetzt noch alle
Variablen als Integer definiert werden, wird’s bestimmt schneller.

@Memnarch

Wenn Du linear äquidistant interpolierst gibt’s nix schnelleres als den Bresenham-
Algorithmus. Funktioniert ja nicht nur bei x/y Koordinaten, sondern auch x/r ,
x/g und x/b . Er ist sehr genau und sehr schnell, da nur Additionen und
Subtraktionen vorkommen.
Es gibt in der Literatur eine Menge an Vorschlägen für seine Optimierung.

Tuning Tip:
Vermeide unbedingt Unterprogramme, Sprünge ( if ... then ... else ) und Schleifen
( for , while , until ) wo immer das geht. Die heutigen CPUs haben sehr lange
execution pipelines und trotz sehr aufwändiger branch prediction geht dabei immer
noch eine Menge an cycles verloren um die pipelines neu zu laden.

Wenn Du irgendwann mal ein wenig von Deinem Code zeigst, können wir Dir bestimmt
noch ein paar Tips geben, wo noch was zu holen ist!

Viel Spaß, bit4bit

Memnarch 31. Mai 2011 10:25

AW: schnelstmöglich dividieren?
 
@Bit4Bit: Den code kann ich leider nciht zeigen. Den habe ich während der Arbeitszeit geschrieben, und ist somit unter Verschluss. Wenn ich das ganze hier zuhause nochmal schreibe, werd ichs mal posten, aber zuhause momentan beschäftigt mit anderen programmen^^


MFG
Memnarch

Memnarch 1. Jun 2011 08:11

AW: schnelstmöglich dividieren?
 
Entshculdigt ich bins nochmal:

@Bit4Bit: in einem der vorherigen Posts hatte ich einen Formelbuffer erähnt. Dabei hatte ich gedacht, dass ich im Ratserizer nicht mehr direkt die Pixel(Farben) berechne, sondern lediglich in einen Buffer pro pixel abspeichere, was ich für den jeweiligen Pixel berechnen muss(also die zahlenwerte). Sobald der Rasterizer durchgelaufen ist, nudel ich dan einfach alle berechnungen des Buffers Durch. Der vorteil wäre, dass ich die Farbwerte eines Pixels 100% niemals doppelt berechne. Eine formel kann bei schlechter sortierung höchstens mehrfach überschrieben werden.

MFG
Memnarch


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:28 Uhr.
Seite 2 von 2     12   

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