Optimierungen noch heute gültig?
-
Hi, habe nur eine kurze Frage:
Ich habe mir erst norlich André LaMothe's Buch "Tricks of the Windows Game Programming Gurus" gekauft. Er sagt da in etwa folgendes:
- Jede Struktur sollte ein Vielfaches von 4-Bytes groß sein, da so groß die Prozessorregister morderner 32bit CPU's sind.
- Um Anwendungen(besonders Spiele) noch mehr zu optimieren, sollten die Strukturen eine Größe eines Vielfachen von 32Byte haben, da sogroß der Cache von "Pentium Class CPU's" ist.
Stimmen 1) und 2) noch?
Sind die AthlonXP und P4 auch noch "Pentium Class CPU's"?
Der AXP hat ja 128KByte L1 Cache und 256/512KByte L2 Cache. Hab ich da was mit dem 32Byte großen Cache von "Pentium Class CPU's" falsch verstanden?THX
PH
-
nr. 1 machen die compilier schon seid ewigkeiten automatsich, nennt sich padding bytes
-
wichtige werte sind 4,32 und 4096
die cpu ließt immer mindestens 4byte, also wenn du mal etwas mit 1byte hast, dann ließt er trotzdem 4, dann werden die unnötigen wegmaskiert, also ist 4 wichtig.
32byte ist eine cacheline, es werden immer 32byte in den cache geladen (gilt für alles ab pentium, ach noch atlhonxp und p4), also wenn du jedes zweiunddreisigste byte lesen würdest aus 1mb, würde das ganze mb durchtransportiert werden, weil der cache sich nur merk welches 32byte segment im cache ist muss er immer 32byte laden, also immer versuchen classes auf 32byte zu trimmen, wenn auf sie nicht linear zugegriffen wird.
falls du sie dynamisch anlegst, dann mußte davon ausgehen dass wegen dem new-operator 16byte davor gepackt werden.
isse kann auch nur richtig allignte datensätze lesen soweit ich weiß.4096byte ist das sogenante knie des speichermanagement (sollte man auch was zu auf google finden) das ist die größe eines speichersegments die ein OS managen muss (falls es sich überhaupt mit "gutes speichermanagement" betiteln düfen will.. win9x mit 64kb sind somit schon deswegen dreck)
wenn man also ein speichermanagement für sein spiel macht, in dem man gleichartike dinge in einem etwas engerem speicherbereich zusammenfasst um mehr cachehits zu bekommen, sollten die blöcke 4kb sein.rapso->greets();
ps. durch gute optimierung für diese dinge hab ich schon doppelte performance bekommen, gerade weil bei neuen systemen der speicher oft das ist, was bremmst.
-
32byte ist eine cacheline, es werden immer 32byte in den cache geladen (gilt für alles ab pentium, ach noch atlhonxp und p4), also wenn du jedes zweiunddreisigste byte lesen würdest aus 1mb, würde das ganze mb durchtransportiert werden, weil der cache sich nur merk welches 32byte segment im cache ist muss er immer 32byte laden, also immer versuchen classes auf 32byte zu trimmen, wenn auf sie nicht linear zugegriffen wird.
falls du sie dynamisch anlegst, dann mußte davon ausgehen dass wegen dem new-operator 16byte davor gepackt werden.
isse kann auch nur richtig allignte datensätze lesen soweit ich weiß.D.h. theoretisch bringt es nichts, wenn ich alle Strukturen auf ein Vielfaches von 32Bytes padde? Denn wenn ich sie padde, dann fülle ich sie ja mit unsinnigen DummyBytes, und wenn ich sie nicht padde, werden sie auch nur mit Müll gefüllt.
Also ist es doch egal oder nicht?Padenn irgendwelche Compiler auf 32Bytes schon automatisch?
wenn man also ein speichermanagement für sein spiel macht, in dem man gleichartike dinge in einem etwas engerem speicherbereich zusammenfasst um mehr cachehits zu bekommen, sollten die blöcke 4kb sein.
Kannst du dazu mal ein Beispiel geben? HAbe es noch nicht wirklich verstanden.
ps. durch gute optimierung für diese dinge hab ich schon doppelte performance bekommen, gerade weil bei neuen systemen der speicher oft das ist, was bremmst.
Genau das ist mein Problem. Ich habe ein Spiel, was meiner Meinung nach zu langsam läuft. Aber mal sehen, vielleicht bekomme ich das auch noch ordentlich optimiert
THX
PH
-
Ja, ich denke auch, daß es daaa nich' so drauf ankommt.
Und wenn Du Dir das Buch gekauft hast, wirst Du wohl noch (mehr oder weniger) Neuling in der Materie sein. Dann mach' Dir mal keinen Kopp wegen zu kurzen structs oder ähnlichem Firlefanz. Und fang' nicht schon während dem Coden an Sachen zu optimieren (mach' ich zwar auch öfters) - dat is'et schlimmste, watte machen kannst. Wenn Du einmal die Droge "on-the-fly-Optimieren" geschluckt hast, kommst Du aus diesem Sumpf nie mehr raus, und Dein Code wird niiiie fertig...
In dem Buch schreibt er auch, er will niemals "Mehrfach-Vererbung" sehen...
In gewisser Weise hat er recht, da das vieles verkompliziert. Und wenn man kaum'n Peil davon hat, wird einem "multiple inheritance" zur Verzweiflung bringen. Trotzdem, wenn man't erstmal kann, ist Mehrfach-Vererbung in der Spiele-Programmierung sicher auch gut aufgehoben.
Aber mach' Dich jetzt net wegen so struct-Größe Sachen verrückt, dat is' Quatsch.BTW, ich finde es paßt hier auch irgendwie rein, also ma' 'ne Frage:
'n BOOL hat ja eigentlich nur 2 mögliche Werte: TRUE oder FALSE, käme also mit 1 Bit aus.
In der ANSI-C Beschreibung hat'et aber'n paar Bytes, wenn mich nicht alles täuscht.
Friemelt der Compiler denn auch immer 8 Booleans in ein Byte rein, oder werden tatsächlich für jeden sch**ß Boolean soundsoviel Bytes belegt!?!MfG, Sarge
-
Boah, und schon wieder 3 neue Beiträge...
Tipp' ich echt so langsam!?!ps. durch gute optimierung für diese dinge hab ich schon doppelte performance bekommen, gerade weil bei neuen systemen der speicher oft das ist, was bremmst.
Im Ernst!?! Das ist ja interessant...
Krass, hätt' ich nicht gedacht...
Dann wird dat auch "irgendwann mal" gemacht...CU, Sarge
-
worum es bei den 32byte grenzen geht ist, dass du variablen die nacheinander benutzt werden hintereinander packst.
angenommen hast einen software renderer und du merkst dir imm rgba werte, änderst aber ganz oft nur den alpha wert (oder ließt dort statusinformationen wie z.B. höche der landschaft aus), dann würde aber jedesmal beim lesen vom speicher rgb mitgeladen werden, wozu?
in diesem fall müßte man sich überlegen ob man nicht rgb und alpha getrennt in arrays speichert, so würdest du immer 32alphawerte in eine cacheline (32byte) bekommen anstatt "nur" 8. die chance dass die gewollten werte dann noch im cache sind, ist höcher.
anderes besipel:
du hast eine classclass CEinheit { public: int m_ID; float m_PosX, m_PosY, m_PoyZ; float m_Speed; float m_Energie; float m_Shilde; float m_Richtung_X; float m_Richtung_Y; float m_Richtung_Z; char m_Name[24]; };
die class schaut doch nicht schlecht aus, hat 64 byte (2*cacheline)
wenn du jetzt ein array hast mit dieser class, dann würdest du vielleicht oft etwas machen wie
for(int a=0;a<EINHEITENANZAHL;a++) { m_Einheit[a].m_PosX+=m_Einheit[a].m_RichtungX*m_Einheit[a].m_Speed; m_Einheit[a].m_PosY+=m_Einheit[a].m_RichtungY*m_Einheit[a].m_Speed; m_Einheit[a].m_PosZ+=m_Einheit[a].m_RichtungZ*m_Einheit[a].m_Speed; }
analysiert man den speichergang, dann siehst du, dass du jedesmal 64byte vom speicher hollst.
wenn du die klasse nun so umstellst
class CEinheit { public: float m_PosX, m_PosY, m_PoyZ; float m_Richtung_X; float m_Richtung_Y; float m_Richtung_Z; float m_Speed; int m_ID; float m_Energie; float m_Shilde; char m_Name[24]; };
wirst du in jedem schleifendurchlauf nur 32byte aus dem speicher hollen müssen.
hoffe ich hab mich nirgens versehen, ansonsten entschuldigung.
padding kannst du als compileranweisung einschalten, sogar für jede class einzeln wenn du magst.
das beispiel für die 4kb.
also, angenommen du hast nen scenengraphen, den du jedes frame durchgehen mußt, weil da viel dynamsich ist,
also:
A
/ \
B Cso als beipsiel, wenn du ihn im speicher so aufbaust das
arrays[]={A,B,C}; ist, damm hast du ja noch gute chancen dass alles in einem speicherblock ist und nicht auf platte ausgelagert wurde.angenommen du lädst aber du den objeckten die an A und C hängen erstmal alles nach, also z.B. die 2mb texturen und legst dann die scenen hierarchie weiter an mit D und E und dann wieder daten und dann F und G und wieder daten.
dann liegen die einzelnen elemente des hierarchiebaums total im speicher verstreuet, also muss z.B. windows damit D und E im speicher bleibt, den ganzen 4kb block drinne behalten und lagert vielleicht oft aus weil du auf diese weise 20mal mehr speicher im ram hast, als du wirklich nutzt.
deswegen legt man sich für sowas oft vorher in einem speichermanager ein 4KB array mit dieser klasse an, die in der scenenhierarchie benutzt wird.
dann kannst du einen kompackt beieinander liegenden scenenbaum haben und viel unnötiges wird ausgelagert.
"Genau das ist mein Problem. Ich habe ein Spiel, was meiner Meinung nach zu langsam läuft. Aber mal sehen, vielleicht bekomme ich das auch noch ordentlich optimiert"
sicher dass das nicht an etwas anderem als am speicher liegt?
rapso->greets();
-
wo kann man sich so'ne cacheline ziehen?
-
Hey cool rapso, hast mir echt schon gut geholfen, thx
Denke habe es jetzt so grob verstanden, werde mal sehen was sich machen lässtUnd fang' nicht schon während dem Coden an Sachen zu optimieren (mach' ich zwar auch öfters) - dat is'et schlimmste, watte machen kannst. Wenn Du einmal die Droge "on-the-fly-Optimieren" geschluckt hast, kommst Du aus diesem Sumpf nie mehr raus, und Dein Code wird niiiie fertig...
Ich bin so gut wie fertig
'n BOOL hat ja eigentlich nur 2 mögliche Werte: TRUE oder FALSE, käme also mit 1 Bit aus.
In der ANSI-C Beschreibung hat'et aber'n paar Bytes, wenn mich nicht alles täuscht.
Friemelt der Compiler denn auch immer 8 Booleans in ein Byte rein, oder werden tatsächlich für jeden sch**ß Boolean soundsoviel Bytes belegt!?!MfG, Sarge
Ja, soweit ich weiß ist zumindest in MSVC++ 6 ein Boolean 1Byte groß, er besteht dann also wirklich aus 7 "Schrottbytes"(die man aber auch anders nutzen kann, wenn man jedes Bit einzelnd anspricht).
sicher dass das nicht an etwas anderem als am speicher liegt?
Ich weiß esnatürlich nicht genau, die Frage mit dem Speicher optimieren war allerdings auch nicht so sehr auf mein Spiel bezogen.
Zu dem Spiel:
Genre: SpaceShooter
Grafik: DDraw4, 800x600, 32bitTB1166,GF4ti4200,256MB DDR RAM,Win2000->Vor Optimierung ca 350-400FPS, jetzt ca 450-500FPS
AMD K6-2 333Mhz, 2MB Matrox Millenium, 48MB EDO RAM,Win98SE->0-1FPS(ca alle 5s ein neues Bild )KAnn es sein, das das Spiel auf dem 333Mhz PC so langsam ist, weil die ganzen Texturen(insgesamt ca 8-9MB) alle nicht in den VRAM passen, und deswegen alle in den RAM ausgelagert werden? Da der so klein ist, werden sie dann noch weiter auf die HD ausgelagert?
Oder was denkt ihr woran das liegt?PH
[ Dieser Beitrag wurde am 12.02.2003 um 16:44 Uhr von Programator editiert. ]
[ Dieser Beitrag wurde am 12.02.2003 um 16:48 Uhr von Programator editiert. ]
[ Dieser Beitrag wurde am 12.02.2003 um 16:49 Uhr von Programator editiert. ]
-
soweit ich weiß kann die matrox mit 2MB kaum noch extra die texturen behalten, eventuell kann sie nichtmal alle von dir verlangten formate mit allen funktionen, daraus kann resultieren dass alles in software läuft (nur vermutung)
wäre ich du würde ich folgendes versuchen.
1. mal ne version mit 16 bit farben (wenns fast doppelt so schnell wird, liegt es wohl am speicher)
2. mal die bildgrößen auf maximal 256 stellen, vielleicht ist die karte so alt dass sie nichts größeres schaft.
3. eventuell solltest du eine 640*480 version anbieten, oder kleinere auflösung.
kann man sich irgendwo screenshots ansehen? ist selten dass hier einer ein fertiges spielchen hat
rapso->greets();
ps. wenn du 500 fps auf einer gf4600 hast, dann sollte dein zeugs schon recht optimal sein.
-
kann man sich irgendwo screenshots ansehen? ist selten dass hier einer ein fertiges spielchen hat
In ca einer Stunde kannste sie dir mal anschauen und runterladen...
Aber erst muss ich mal die neuste Version uploaden:)Wegen den 500FPS auf einer GF4Ti4200 :
Meinste das ist wirklich so optimal? Denn äußerst aufwendig ist das Spiel halt nicht, ist ein "normaler" SpaceShooter.Wegen der 16Bit Version: Es lief bis gestern in 16Bit, allerdings hatte es auch da nur ca 1 FPS
Was mir noch einfällt : Ich habe die Option eingebaut, das Spiel(SpaceBuster) ohne Sound zu starten. Wenn ich den Sound weglasse, läuft es auf meinem 1166er(Konfig siehe oben) mit ca 600-700FPS. Ist die Soundausgabe unter DirectMusic8 wirklich so langsam oder liegt das an meinem uneffizienten Code?
Testen kann man das mit der Option "-nosound" in der Befehlszeile, aber wie gesagt das uploaden dauert noch ca ne std[edit]
So, habe das Ganze jetzt mal hochgeladen, der Link ist :http://de.geocities.com/philippoe2002/SpaceBuster/Page/SpaceBuster.html
Einfach auf der Seite ganz nach unten scrollen, da gibt es dann verschiedene SpaceBuster Files zum runterladen. Einmal den Sourcecode in ZIP und ACE, dann noch das Spiel selber in ZIP und ACE. Im Sourcecode sind aber die zusätzlichen Daten wie Sounds,Bitmaps,etc. nicht enthalten!
HAve Fun
[/edit]PH
[ Dieser Beitrag wurde am 12.02.2003 um 19:19 Uhr von Programator editiert. ]
[ Dieser Beitrag wurde am 12.02.2003 um 19:59 Uhr von Programator editiert. ]
-
gratuliere,
das spiel läuft ziemlich gut, ist aber auch recht schwer mit sovielen gegnern :).
ganz schön gut, 11monate an einem spiel zu coden, selten dass jemand die ausdauer hat
und was steht bei euch als nächstes an?
rapso->greets();
-
ich glaube an deinem fps zähler ist eher was falsch. 500 frames pro sekunde sind viel zu viel. das kriegst du niemals hin!!
-
lol, du hast bei vielen funktion vergessen den rückgabewert anzugeben bsp.
Create(int NewMAXxTyle,int NewMAXyTyle, int NewRotateInterVall);
MSVC 7 warnt dann dauert beim compilieren
-
das spiel läuft ziemlich gut
Cool!
Mit wievielen FPS denn bei ungefähr welchem PC?ist aber auch recht schwer mit sovielen gegnern
Es gibt die level Easy, difficult und hardcore, standard ist difficult
ganz schön gut, 11monate an einem spiel zu coden, selten dass jemand die ausdauer hat
Ja... ich bin jemand der gerne Detailverbesserungen macht
Erst wollte ich nur 4Monate oder so proggen, dann hab ich mir aber immer mehr vorgenommen und immer weiter verbessert.und was steht bei euch als nächstes an?
Eine Art SciFi-Strategiespiel.
Wobei das noch was dauert, wir haben bisher zusammen eine kleine Designmappe entwickelt, in der die wesentlichen Grundzüge halt festgehalten sind.
Allerdings habe ich beim entwerfen auch gemerkt, dass es wohl besser ist wenn ich erstmal D3D lerne-> mehr Speed, Flexibilität(richtiges und keine gefaktes AlphaBlending wie in SpaceBuster , rotieren von Objekten(und kein Laden der einzelnden Bilder)).D.h. ich lerne jetzt erstmal grundsätzlich D3D, der Freund von mir lernt mit 3D-Programmen ein wenig umzugehen, außerdem versucht er sich gerade in der Liedkomponierung Danach geht es dann hoffentlich loß
ich glaube an deinem fps zähler ist eher was falsch. 500 frames pro sekunde sind viel zu viel. das kriegst du niemals hin!!
Das glaube ich kaum Der FPS Zähler arbeitet nach einem extrem einfachen Schema, und ich wüsste nicht warum ich da keine 500FPS hinbekomen sollte...
Ein nach einem anderen Schema arbeitender FPS Counter(siehe Klasse FPSCount) zeigt mir in etwa die gleichen Werte an...lol, du hast bei vielen funktion vergessen den rückgabewert anzugeben bsp.
Create(int NewMAXxTyle,int NewMAXyTyle, int NewRotateInterVall);
MSVC 7 warnt dann dauert beim compilieren
Mich warnt da keiner... und den MSVC++ 7 kannte ich noch garnicht.
Wahrscheinlich nimmt der MSVC++ 6 einfach void als Standard...
Übrigends, ich weiß das der Code schlecht aussiehtPH
[ Dieser Beitrag wurde am 12.02.2003 um 21:17 Uhr von Programator editiert. ]
-
Noch was: Ich hab den Code mit Visual C++ 7 neukompiliert und die EXE in den Ordner reinkopiert mit den ganzen anderen Daten. Im Debug und Release Modus stürzt es beidesmal ab. also is da noch ein fetziger bug
-
ich habs auch neukompiliert mit den Zips die es im Inet gibt...
MSVC++ 6
DXSDK81)AXP1800+, GF2MX, 384MB SDRAM, Winme : OK
2)ATB1166, GF4Ti4200, 256MB DDRRAM, Win2000 : OKSchau dir doch einfach mal die LogFiles an, und schick sie mir evtl wenn du Lust hast. Email ist philipp.oetti@codetown.de !
[edit]Habe es einmal gestartet: Ok
Starte ich es auf dem WinME Rechner jedoch ein zweites mal, stürzt es auf einmal ab. Kann sein das das dein Fehler ist:( ICh check das mal aber thx für die Meldung.
[/edit]
PH[ Dieser Beitrag wurde am 12.02.2003 um 21:34 Uhr von Programator editiert. ]
-
also die exe die dabei war funktioniert. nur wenn ich es neukompiliere und die exe austausche dann schürzt es einfach ab. mit soner messagebox wo er den fehler zu microsoft senden will. also irgendwie keine access violation oder sowas. berichtige aber bitte mal das mit den rückgabewerten. wie kann man sowas nur vergessen?
-
achso. ich hab nen Athlon XP 2000 + GeForce 4 MX und komm nur auf 76 frames. total konstant, ändert sich nie. find ich auch ungewöhnlich. na gut, deine grafikkarte ist besser, aber so extrem glaub ich eigentlich nicht.
-
achso. ich hab nen Athlon XP 2000 + GeForce 4 MX und komm nur auf 76 frames. total konstant, ändert sich nie. find ich auch ungewöhnlich. na gut, deine grafikkarte ist besser, aber so extrem glaub ich eigentlich nicht.
Stell mal erst deinen Monitor auf >75Hz
Und zweitens deinen VSync unter DirectX ausÜbrigends erreiche ich mit nem AXP1800+ und GF2MX nur ca 300FPS...
Das mit den Rückgabewerten werde ich mal überprüfen.
-
hallo! mein monitor funktioniert nur mit 75 hertz. aber ich glaube nicht das deiner mit 300 hertz läuft. aber das mit dem vsync hört sich logisch an. danke für den tipp. muss nur noch rausfinden wo das geht.