![]() |
schnelstmöglich dividieren?
Tag allerseits, also:
ich habe eine Formel:
Delphi-Quellcode:
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).
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; 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 |
AW: schnelstmöglich dividieren?
Threaden. Du hast 2 Kerne (wg. Hyperthreading), also nutze auch beide.
|
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 |
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); |
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. |
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 |
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.
|
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 ![]() |
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 |
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:
Wie bereits zu sehen ist ist die kalkulierung des Faktors so rausgekürtzt dass ich pro Farbwert nur einmal dividiere.
Rotwert := (FlächeA*RotA + FlächeB*RotB + FlächeC*RotC) div Gesamtfläche;
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 |
AW: schnelstmöglich dividieren?
FixedKomma ist der DatenTyp Currency (der arbeitet intern als Int64)
|
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 |
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:
Currency wird aber als ein Befehl über die FPU behandelt, wie die normalen Float-Typen auch.
{ 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; 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. |
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 |
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
![]() 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. |
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.
|
AW: schnelstmöglich dividieren?
Du kannst statt der Farben doch auch einfach die Z-Koordinate da einsetzen :)
Wofür brauchst du die eigentlich? |
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 |
AW: schnelstmöglich dividieren?
Ich meinte die Z-Coords :) Gouraud-Shading war klar.
|
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. |
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 =) |
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) |
AW: schnelstmöglich dividieren?
Eventuell könnte dir vielleicht auch, je nach Komplexität und Polygonanzahl, die Technik des
![]() |
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:
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!
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; Ich habe aber selbst noch nicht mit SSE gearbeitet, daher kann ich es nur oberflächlich beschreiben... |
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 ![]() 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 :) |
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 ? |
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 |
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; |
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. |
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. |
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.) |
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 :)
|
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; |
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. |
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) |
AW: schnelstmöglich dividieren?
@Memnarch
Versuch doch mal folgende Idee (nicht getestet) :
Delphi-Quellcode:
Normalerweise müsste der Compiler das gut optimieren können.
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; Wenn nicht, hilft Assembler. Da das Ergebnis in 2 Bytes passt, kannst Du nach der Multiplikation einfach den Inhalt von DX benutzen. MfG bit4bit |
AW: schnelstmöglich dividieren?
@bit4bit;
Delphi-Quellcode:
Und welche Ergebnisse erwartest du ?
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; 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. |
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: ![]() 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 ![]() MFG Memnarch |
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 |
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 19:57 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