|
Dakuan
Anmeldungsdatum: Nov. 2, 2004
Beiträge: 4093
Wohnort: Hamburg
|

2. Juli 2012 22:23
Nach mehr als 10 jähriger Pause befasse ich mich wieder mit einfacher Grafikprogrammierung. Aus Performancegründen wurde damals für die umfangreichen Berechnungen oft Festkommaarithmetik benutzt. Ich habe jetzt mal einen Test gemacht, und konnte keinen wirklichen Unterschied feststellen, Allerdings kann ich auch nicht genau sagen ob mir der Compiler durch irgendwelche Optimierungsmassnamen das Ergebniss verfälscht und wie man einen solchen Test anlegen muss. Jedenfalls hatte ich anfangs große Unterschieden, bis ich darauf gekommen bin, das viel Zeit mit der Konvertierung von float zu long und umgekehrt verdaddelt wird. Ich habe auch keine Ahnung, ob der Compiler erkennt, das sich die Werte egentlich nicht ändern und das einfach wegoptimiert. Deshalb frage ich hier einfach mal. Kann es sein, das sich solche Tricks wie Festkommaarithmetik heute nicht mehr lohnen, weill jede CPU eine FPU integriert hat und diese schneller ist als 2 longs zu multiplizieren (oder macht das jetzt auch die FPU?). Nachtrag: Ach ja, wie sieht da mit Wikelfunktionen aus? Es wird ja fast jedesmal sowohl der Sinus als auch der Kosinus des jeweiligen Winkels benötigt. Da wurden damals oft Tabellen benutzt, das das deutlich schneller war als die normalen Funktionen.
|
|
Darkstar999
Anmeldungsdatum: Sept. 21, 2008
Beiträge: 324
|

2. Juli 2012 23:31
Dakuan schrieb: Ich weiß nicht ob dir das weiterhilft das einzige was ich dazu weiß ist das Cpu schnell ist bei Subtraktion und Addition und Gpu bei Multiplikation und Division . Was auch ein Grund dafür ist warum heutzutage Gpus als Hilfe bei gewissen Softwarelösungen genutzt werden. mfg Darkstar999 Edit: Meinst du mit Winkelfunktion z.B Drehungen von Grafischen Objekten ?
|
|
stfischr
Supporter
Anmeldungsdatum: März 1, 2007
Beiträge: 15447
|

3. Juli 2012 01:03
Hi. Gab es sowas wie SSE nicht auch schon vor 10 Jahren? Bei einzelnen Berechnungen ist SSE zwar langsamer aber durch die Parallelität und das Pipelining ist man am Ende deutlich schneller. Ich würde auch mal vermuten, dass dir dein Compiler SSE-Code erzeugt. Zeige doch mal den Quelltext, dann kann man das auch schön debuggen und analysieren. Was genau ist bei dir "Grafikprogrammierung", sollte man sowas nicht per OpenGL auf der Graphikkarte machen?
|
|
user unknown
Anmeldungsdatum: Aug. 10, 2005
Beiträge: 13796
Wohnort: Berlin
|

3. Juli 2012 11:26
Die letzte Intel-CPU ohne FPU war m.W. der 386, zu dem es einen 387 gab, wenn es sich lohnte. Ab Pentium war es dann in der Intelfamilie drin. Was Atom und AMD betrifft bin ich aber nicht auf dem laufenden.
... das Ergebniss verfälscht und wie man einen solchen Test anlegen muss.
Realistisch. Wenn Du immer nur 4 Punkte/s berechnest macht es wenig Sinn die CPU zum Glühen zu bringen - willst Du aber fortlaufend berechnen soviel wie geht dann solltest Du auch genau das messen. Du hast uns nicht mal verraten ob Du mit C, C++, Assembler, Java, Python oder womit Du arbeitest. Mit "Compiler" ist Python wohl raus.
bis ich darauf gekommen bin, das viel Zeit mit der Konvertierung von float zu long und umgekehrt verdaddelt wird.
Dass da viel Zeit verbraten wird heißt ja nicht dass es überflüssig ist - wenn Du darauf verzichten kannst - wieso machst Du es dann?
Werte egentlich nicht ändern und das einfach wegoptimiert.
Im Gegensatz zu 'nicht ändern' - was ist eigentlich nicht ändern? Wenn der Compiler das feststellen würde, dann könnte man ja 2 Varianten des Codes compilieren, und nachschauen, ob der gleiche Code erzeugt wird.
weil jede CPU eine FPU integriert hat und diese schneller ist als 2 longs zu multiplizieren
Heute haben viele PKW einen Turbolader und sind damit schneller als von Wolfsburg nach Dortmund.
Da wurden damals oft Tabellen benutzt, das das deutlich schneller war als die normalen Funktionen.
Das dürfte ja unter anderem von der Größe der Tabellen abhängen und damit davon, wie oft man die braucht, und die Güte des Ergebnisses ebenfalls, womit wir bei der benötigten Präzision sind. Dazu wissen wir nichts denn auch dazu hast Du nichts verraten.
|
|
Dakuan
(Themenstarter)
Anmeldungsdatum: Nov. 2, 2004
Beiträge: 4093
Wohnort: Hamburg
|

3. Juli 2012 11:56
Edit: Meinst du mit Winkelfunktion z.B Drehungen von Grafischen Objekten ?
Genau das meine ich. Da werden elend lang Matritzen multipliziert und Sinus/Cosinus treten immer Paarweise auf.
Was genau ist bei dir "Grafikprogrammierung", sollte man sowas nicht per OpenGL auf der Graphikkarte machen?
Ja, wenn man das in Echtzeit machen will. Und ich habe noch keine Ahnung wie ich unter Gnome da rankomme oder ob das bei SDL automatisch dabei ist. Momentan beschränke ich mich erstmal darauf direkt BMP Bilder zu erstellen. Ist ja erstmal egal, ob die erzeugte Bitmap als Bild weiterverarbeitet wird oder in den Bildschirmpuffer kommt. Jedenfalls bin ich jetzt soweit, das ich mir ein zweckmäßiges Dateiformat überlegen muss. Als ich früher meine Objekte für die DOS Version des MS Flugsimulators gebastelt hatte, mussten Skalierungswerte und Normalenvektoren der Polygone immer im Festkommaformat angegeben werden und ich frage mich, ob das heute auch noch nötig ist.
Zeige doch mal den Quelltext, dann kann man das auch schön debuggen und analysieren.
Ok, das ist mir jetzt zwar etwas peinlich, aber ich sgte ja bereits, das ich keine Ahnung habe, wie man einen solchen Test anlegt.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 | /*
** Geschwindigkeitstest für Kestkomma Multiplikation
*/
#include <stdio.h>
#include <stdlib.h>
float
get_fval( float v )
{
return v;
}
long
get_lval( int v )
{
return (long)v;
}
float
dummy_f( float v )
{
return v;
}
long
dummy_l( long v )
{
return v;
}
int
main( int argc, char * argv[] )
{
int i, j, k;
float x, y;
long l1, l2;
printf( "float ...\n" );
for( i = 0; i < 300; i++ ) {
for( j = 0; j < 1000; j++ ) {
for( k = 0; k < 1000 ; k++ ) {
x = get_fval( 3.0 );
y = get_fval( 7.0 );
dummy_f( x * y ); /* <===! */
}
}
}
printf( "long ...\n" );
for( i = 0; i < 300; i++ ) {
for( j = 0; j < 1000; j++ ) {
for( k = 0; k < 1000 ; k++ ) {
l1 = get_lval( 3072 );
l2 = get_lval( 7168 );
dummy_l( (l1 * l2) >> 10 ); /* <==! Kommakorrektur */
}
}
}
printf( " --- end ---\n" );
return 0;
}
|
Mit den umständlichen Dummy Funktione wollte ich übrigens verhindern, das der Comiler sagt, der Code habe keinen Effekt und ihn deshalb einfach weglässt. Ich habe jetzt aber den Verdacht, das ich eigentlich die Zeit für die Funktionsaufrufe gemessen habe. Nachtrag: dann solltest Du auch genau das messen.
Dann muss ich wohl in den sauren Apfel beissen und zum Vergleich eine Matrizenmultiplikation mit Festkommawerten implementieren ...
|
|
Darkstar999
Anmeldungsdatum: Sept. 21, 2008
Beiträge: 324
|

3. Juli 2012 12:35
Dakuan schrieb: Edit: Meinst du mit Winkelfunktion z.B Drehungen von Grafischen Objekten ?
Genau das meine ich. Da werden elend lang Matritzen multipliziert und Sinus/Cosinus treten immer Paarweise auf.
Sinnvoller weise sollte man doch dafür die Gpu einbinden(nutze) Da die Stärke der Gpu bei Multiplikationen liegt. Aus genau diesem Grund von Komplexen Matrixoperationen, wo definitiv die Gpu schneller ist heutzutage wird die Cpu auch bei Passwortknackaktionen verwendet von gewisser Software da sie da allemal schneller ist als die Cpu. Sdl hat eine Opengl Schnittstele (Anbindung) wie hier im Tutorial gut beschrieben. http://www.tomprogs.at/tutorials/spieleentwicklung/cpp-opengl-initialisieren-mit-sdl.xhtml mfg darkstar999 Edit :Für Laufzeit Messungen empfehle ich die Netbeans die IDE hat das mit eingebaut und du kannst das am Aktuellen Code testen. Solche Tests wie oben von dir gemacht sind zu ungenau 1. Compiler Optimiert den Quelltext 2. anderer Code andere Laufzeiten dafür ist die Laufzeitanalyse einfach zu Parameter abhängig!
|
|
stfischr
Supporter
Anmeldungsdatum: März 1, 2007
Beiträge: 15447
|

3. Juli 2012 13:56
Also wenn ich das sehe, vermute ich mal, dass 90% der Zeit mit Funktionsaufrufen verplempert wird. Ich denke auch, das du an das Gesamtprojekt falsch heran gehst. Ich würde erstmal schauen, ob es fertige Frameworks für deine Aufgabe gibt. Wenn nicht würde ich die nötige Engine über OpenGL implementieren. Da muss man sich dann auch nicht um die Drehung kümmern, es gibt fertige Funktionen wie glRotate, die auf (Graphik)Hardware zurückgreifen, welche deine bisherigen Ansätze lächerlich langsam erscheinen lassen. PS: Optimierungen wie float/fixed stehen üblicherweise nach Vollendung des Projektes an, falls sich an dieser Stelle tatsächlich ein Flaschenhals befindet. Kapsle solche Funktion ordentlich, dann sind sie auch schnell und leicht optimiert/ausgetauscht.
|
|
chilidude
Anmeldungsdatum: Feb. 18, 2010
Beiträge: 214
|

3. Juli 2012 20:13
Dakuan schrieb:
Deshalb frage ich hier einfach mal. Kann es sein, das sich solche Tricks wie Festkommaarithmetik heute nicht mehr lohnen, weill jede CPU eine FPU integriert hat und diese schneller ist als 2 longs zu multiplizieren (oder macht das jetzt auch die FPU?).
Festkommarithmetik (CPU) ist nicht gleichzusetzen mit Gleitkommaarithmetik (FPU). Es hängt vom zu speichernden Format ab. Vorteil vom Festkomma sind die schnellen Schiebebefehle und die ausschliessliche Beschänkung auf die Cpu. Im Prinzip hat aber jeder Cpu-Kern auch eine dazugehörige Fpu. Ausnahmen sind Prozessoren, wo zwischen Kernen und Threads unterschieden wird. Hier stehen die Threads für die Zahl der Cpu-Kerne und die Kerne für die FPU's. Ob du dich für die Cpu oder Fpu entscheidest hängt von den Compilereinstellungen ab. http://de.wikipedia.org/wiki/Festkommazahl
Nachtrag: Ach ja, wie sieht da mit Wikelfunktionen aus? Es wird ja fast jedesmal sowohl der Sinus als auch der Kosinus des jeweiligen Winkels benötigt. Da wurden damals oft Tabellen benutzt, das das deutlich schneller war als die normalen Funktionen.
Du kannst dazu immer noch Tabellen verwenden. Die Fpu hat dafür aber auch direkte Befehle, die auf jeden Fall schneller sein dürften.
|
|
posti
Anmeldungsdatum: März 30, 2009
Beiträge: 2076
|

3. Juli 2012 20:46
Nur ein Einwurf: sin/cos berechnet die FPU schneller, als die CPU in einer Tabelle eine Zahl rauskopiert? Von der Genauigkeit oder Zwischenpositionen mal abgesehen. MfG
|
|
Dakuan
(Themenstarter)
Anmeldungsdatum: Nov. 2, 2004
Beiträge: 4093
Wohnort: Hamburg
|

3. Juli 2012 22:35
sin/cos berechnet die FPU schneller, als die CPU in einer Tabelle eine Zahl rauskopiert?
Ich habe inzwischen gelesen, Das FPUs oft auch intern mit Tabellen arbeiten um den Startwert einer Reihenentwicklng zu bestimmen und dann so lange weiterrechnen, bis die geforderte Genauigkeit erreicht ist. Ich denke ich werde einfach mal so tun, als wenn das heute kein Thema mehr ist und dann mal sehen was passiert. Festkommarithmetik (CPU) ist nicht gleichzusetzen mit Gleitkommaarithmetik (FPU).
Das ist mir bekannt. Festkommaarithmetik ist / (war) immer ein Ballanceakt zwischen der Mindestgenauigkeit und der Gefahr eines Überlaufs.
Ich würde erstmal schauen, ob es fertige Frameworks für deine Aufgabe gibt. Wenn nicht würde ich die nötige Engine über OpenGL implementieren.
Ich glaube nicht, das ich da was fertiges finde, denn ich spiele auch mit dem Gedanken die alten FS Objekte aus der damaligen Zeit in 3D Bilder zu verwandeln, die dann (hofentlich) auch mein Fernseher erkennt. Einige andere Autoren von damals hatten mir ihre Objektdteien zugesandt. Wenn man sowas heute sieht, könnte man meinen sie währen mit 3D Studio Max erstellt, dabei waren es in einem Fall 5 Disketten reine Handarbeit.
|
|
TraumFlug
Anmeldungsdatum: Juli 16, 2009
Beiträge: 909
Wohnort: zwischen den ohren
|

4. Juli 2012 02:14
Festkommaarhythmetik (weil, die hat rhythmus...) würde ich nur noch einsetzen in Fällen wo: 1) konstante Genauigkeit auf einen konstanten Wertebereich bezogen Bedingung/vorteilhaft ist. Fixkomma kann z.B. "genauer" sein als Fliesskomma, beispielsweise 32bit Bereich 0.0-1.0 - Fliesskomma ist gegen null wahnsinnig feinauflösend, baut aber nach oben hin ab, Fixkomma konstant - je nach Algorithmus/Verwendung vor/nachteilhaft; man denke an eine Position in einem grossen Raster (spricht für fix) gegen sowas wie eine Winkelgeschwindigkeit, die auch mal sehr klein sein kann (spricht für float). 2) (...vielleicht...) 2 unabhängige Recheneinheiten, auch auf verschiedenen cpu's bei den exakt gleichen Berechnungen exakt das gleiche Ergebnis liefern sollen (bei fliesskomma mit sse vielleicht auch gegeben? infos bitte... ) 3) Fliesskommaberechnungen sehr viel langsamer sind als Integeroperationen, z.B. embedded geräte, ganz alte cpu's und so zum Thema sin/cos etc.: ja, die transzendentalen sind eher langsam bei floats, dafür genau. Bei fixed noch mehr, weil von float konvertiert wird. Braucht man viele schnell, egal ob fix oder float, gibt's Annäherungen, z.B. über interpolierte Tabellen, oder z.B. wenn's einfach "wabbeln" soll, eine Parabelfunktion (x^2) so umwandeln, dass sie annähernd einer Sinuskurve entspricht. Das gleiche gilt für Quadratwurzeln, Potenzen (vor allem von Bruchwerten), Divisionen, und dergleichen. Zum Testen erstmal "naiv" implementieren (libm funktionen), dann, wenn's wirklich zu langsam ist, und der Algorithmus an sich gut genug ist, Annäherungen/Tricks untersuchen (Websuche findet zu allem den einen oder anderen algo, variable qualität), und vor allem untersuchen, ob die Genauigkeit wirklich nötig ist, und wenn ja wieviel. Z.b. bei Geomettriewandlungen ist es oft nicht nötig, weil oft eine Matrix erzeugt wird (paarmal "echte" sin/cos), und dann Massen an daten durch multiplikation und Addition mit dieser Matrix verarbeitet werden. Braucht man natürlich pro Punkt eine Eigenständige Transformation, und hat viele Punkte, muss man tricksen. Insgesammt benutzen z.B. die meisten vektorbasierten Spiele für das Meiste Fliesskomma, OpenGL kommt auch sehr gut damit klar, die Grafikhardware liebt floats. Man braucht natürlich eine gute Bibliothek/Framework/Engine um damit zu arbeiten, denn OpenGL kümmert sich nur darum rohe Daten zu schlucken um sie zu Rendern, alles Andere "macht man selbst". OpenGL beschleunigt dabei das Gröbste, so möglich. Gewitzte Optimierungen auf der Grafikhardware sind, in Zeiten von Shadern und GLSL übrigends auch bei OpenGL durchaus gefragt...genauso wie es viel Sinn macht, stark zu filtern was man wann und wie auf den Grafikchip pumpt. Aber das ist eine Wissenschaft für sich. OpenGL programmiert sich auch ganz ganz anders als "klassische" 3d renderer aus der alten Schule. Was man wie optimiert ist natürlich immer eine Frage was genau man erreichen will, da geht's nichtnur um reine Technikaspekte, sondern auch um Planung des gesamten Komplexes. Um da wirklich Ratschläge geben zu können, müsste man wissen, was du genau im Endeffekt planst. Wenn du einfach alte 3d Objekte laden & darstellen willst, und das Format kennst, vielleicht ist Blender was für dich? Blender ist komplex und nicht leicht zu erlernen, man kann aber selbst skripte zum Laden von eigenen Formaten in Python schreiben, und die Renderingergebnisse gehen durchaus in Richtung Photoreal, wenn man geschickt ist - viel besser als reines OpenGL. Ob moderne 3d Formate gehen, weiss ich jetzt nicht aus dem Stand, man kann aber sehr wohl stereoskopische Bilder rendern (ist ja nur 2 Bilder, die Kamera nach links/rechts versetzt). P.S.: zum thema alu(integer) und fpu(float) fällt mir immer wieder michael abrash ein, der in seiner zeit bei id-software für quake eins für 386 optimiert hat, und berechnungen beider einheiten so gemischt hat, dass möglichst hoher durchsatz entsteht - um das spiel auf schwachen komputern noch gut spielbar zu machen. hexenwerk war das, er hat auch ein dokument ("black book of coding" oder so) dazu in's netz gestellt, wo er das ansatzweise beschreibt. lesenswert, obwohl heutzutage sowas bei der komplexizität und vielfalt der systeme garnichtmehr sinnvoll ist, ausser man will "grosse kunst" schaffen...
|
|
stfischr
Supporter
Anmeldungsdatum: März 1, 2007
Beiträge: 15447
|

4. Juli 2012 09:50
TraumFlug schrieb: 2) (...vielleicht...) 2 unabhängige Recheneinheiten, auch auf verschiedenen cpu's bei den exakt gleichen Berechnungen exakt das gleiche Ergebnis liefern sollen (bei fliesskomma mit sse vielleicht auch gegeben? infos bitte... )
Solange man in seinem Compiler nicht ungenaue Berechnungen explizit erlaubt sind die Ergebnisse sowieso überall gleich. http://de.wikipedia.org/wiki/IEEE_754
|
|
Darkstar999
Anmeldungsdatum: Sept. 21, 2008
Beiträge: 324
|

4. Juli 2012 10:05
stfischr schrieb:
Solange man in seinem Compiler nicht ungenaue Berechnungen explizit erlaubt sind die Ergebnisse sowieso überall gleich. http://de.wikipedia.org/wiki/IEEE_754
Richtig! I triple E ist ne feine Sache! Das erinnert mich irgendwie an Digital und RechnertechnikI rein in die Kartoffeln und raus aus den Kartoffeln!
Sorry Offtopic! mfg darkstar999
|
|
Dakuan
(Themenstarter)
Anmeldungsdatum: Nov. 2, 2004
Beiträge: 4093
Wohnort: Hamburg
|

4. Juli 2012 23:08
..genauso wie es viel Sinn macht, stark zu filtern was man wann und wie auf den Grafikchip pumpt.
Ja, das ist auch wieder so ein Punkt. Wenn ich da in den Beispielen aus alten Büchern sehe wie da zu jedem Polygon der Normalenvektor berechnet wird um festzustellen ob das Ding überhaupt sichtabr ist (weil Rückseite)... Beim alten FS5 war der Normalenvektor Bestandteil der Objektdatenbank, wurde also schon vorverarbeitet. Allerdings muss der dann auch mit durch die Rotationsmatrizen. Das klingt dann auch wieder nach der Wahl zwischen Pest und Cholera. Aber alle sind sich einig, je früher man filtern kann, um so besser. Bis jetzt habe ich aber nur 3 Würfel, da spielt das noch keine Rolle. Bei der Genauigkeit sieht das schon anders aus. Der Ur-Flugsimulator kam z.B. mit einer Winkelauflösung von ca. 1.4 Grad aus. Der Kreis wurde einfach durch 256 geteilt. Das mag man sich heute natürlich nicht mehr antun.
Was man wie optimiert ist natürlich immer eine Frage was genau man erreichen will, da geht's nichtnur um reine Technikaspekte, sondern auch um Planung des gesamten Komplexes. Um da wirklich Ratschläge geben zu können, müsste man wissen, was du genau im Endeffekt planst.
Da hast du mich jetzt aber auf dem falschen Fuß erwischt. Erstmal will ich probieren was machbar ist und wie die damals erstellten Objekte auf einem großen Bildschirm wirken, insbesondere als 3D Bilder. Aber dann ist mir auch schonmal die Idee gekommen mit SDL sowas wie ein Irrgaren zu probieren, etwa so wie das früher auf einigen Handys dabei war. Aber wenn ich dann morgens aufwache, bin ich nicht sicher, ob ich am Vorabend nicht doch zu übermütig war.
Wenn du einfach alte 3d Objekte laden & darstellen willst, und das Format kennst, vielleicht ist Blender was für dich?
Mit Blender hatte ich schonmal experimentiert. Das ist wirklich eine eigene Welt. Wenn ich das Dateiformat kennen würde, könnte ich ja einen Konverter schreiben, aber ich fürchte das es da in jedem Format Dinge gibt, die keine Entsprechung im anderen haben, sodass neukonstruieren möglicherweise schneller ist.
P.S.: zum thema alu(integer) und fpu(float) fällt mir immer wieder michael abrash ein, der in seiner zeit bei id-software für quake eins für 386 optimiert hat,...
Das der bei ID-Software war wusste ich nicht. Ich kenne ihn nur von seinen Artikeln im Dr. Dobb’s Journal, als es das noch auf Papier gab. Aber ich habe nicht vor, meine Experimente auf mein altes 600 MHz EPIA Board auszuweiten. Das Ding hat schon genug damit zu tun, meine Squeezebox zu füttern. Und ich denke, um zu verstehen, was so ein gewiefter Hexenmeister da so macht, muss man sich auch in der Hardware gut auskennen. Und das ich die heutige Hardware nicht so gut kenne folgt ja schon aus meiner Fragestellung.
|
|
stfischr
Supporter
Anmeldungsdatum: März 1, 2007
Beiträge: 15447
|

5. Juli 2012 00:34
Eigentlich ist es heute besser, wenn man nicht so viel über die Hardware weiß. Gibt viele verschiedene Architekturen mit Besonderheiten, solange es nicht extrem kritisch ist, einfach den Kompiler optimieren lassen.
|