XNA 2D wie programmiere ich richtig? CPU auf Vollast

Murphy9904

Lt. Junior Grade
Registriert
Mai 2007
Beiträge
344
Hi,
ich hab mir mal in XNA so n Tutorial durchgemacht nachdem ich denke ich mal ein paar der Grundlagen behersche.

hier das Turorial

also nach dem Prinzip hab ich dann mal versucht mein eigenes Spiel zu programmieren.
hab mich an Doodle Jump versucht - kennt sicher jeder

wollte einfach eine 1:1 umsetzung für den PC machen.

für jede Plattform die es da gibt mach ich dann immer ein Update und überprüfe die position von dem Hüpfenden Fich immer pixelgenau 60 mal in der sekunde.. so wie das in dem tutorial auch alles gemacht wird.. dadurch ist meine letzte CPU aber auf Volllast. - meiner Meinung nach is das bei sowas einfachen doch nich richtig ?!

Fragen:
is das bei XNA normal dass die CPU überlastet wird, weil rucken tuts ja nich...
kann ich irgendwie performanter Programmieren?
Wieso wird nur eine CPU genutzt wenn er bei 100% auslastung ist?

Danke schonmal
Murphy
 
Vermutlich lässt du dein Programm in der Hauptschleife aktiv auf ein Event (Timer, etc.) warten. Das frisst dir die CPU auf, da er kontinuierlich überprüft, ob was passiert ist. Besser ist es ein passives Warten zu programmieren. Da wird er nur dann aufgeweckt, wenn das entsprechende Event aufgetreten ist.
Es würde vermutlich schon reichen, so was wie Thread.Sleep(10); (oder so ähnlich geschrieben) in die Warteschleife einzubauen.


Mehrere Kerne kannst du dann nutzen, wenn du mit mehreren Threads arbeitest. Das kann ein Compiler nicht für dich machen. Deshalb liegt darin auch die Kunst.
 
Zuletzt bearbeitet: (Typo)
Ja das stimmt ich prüfe alles Aktiv auf veränderung und so.
ich hab bei xna aber noch keine Events gesehn. Gibt's da überhaupt welche?

vorallem überprüfung auf Kollision von 2 objekten frisst viel rechenleistung - kann ich solche events auch selbst schreiben?


okay das klingt logisch, dann sollt ich mir thrading ma genauer anschaun :)
 
Also ich hab hier ein simples XNA Projekt, wo sich nur ein Polygon dreht. Das verursachte auch 25% CPU-Last. Dann hab ich eben mal spaßeshalber an dieser Eigenschaft rumgespielt: http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.game.isfixedtimestep.aspx
Und jetzt verbraucht es 0% CPU. Komischerweise lassen sich die 25% nicht mehr reproduzieren. Du kannst also mal in der Initialize-Methode versuchen, IsFixedTimeStep auf true zu setzen. Vlt hilft es.
 
hmm hat nichts gebracht..
kann ich irgendwie herrausfinden welche Codestellen am öftesten aufgerufen werden um diese zu Optimieren?
 
Dafür verwendet man Profiler. Die zeigen an, welches Stück Code am längsten braucht.
Ich glaube, die muss man extra kaufen.
 
Hmm okay
naja von hand kann ich ja auch durchgucken wo ich unnütze sachen mache
vllt wirds dann besser

danke euch :)
 
Im Normalfall wird dort die meiste Zeit gebraucht, wo Schleifen sind.
 
e-Laurin schrieb:
Es würde vermutlich schon reichen, so was wie Thread.Sleep(10); (oder so ähnlich geschrieben) in die Warteschleife einzubauen.

Oh, sehr böse bei XNA. Dafür gibt es wie bereits gesagt "IsFixedTimeStep" und damit zusammenhängende Konsorten. Weiterer Ansatz:
Im Vollbildmodus wird immer ein Thread der CPU voll ausgelastet. Das ist normal bei XNA und soweit ich weiß auch bei anderen Spielen(?).

Wie wär´s, wenn ihr mal nach dem Code fragt, anstatt ihm für seine 10 Zeilen gleich einen Profiler anzudrehen?
 
Zuletzt bearbeitet:
hab paar sachen geändert aber manchmal geht die Cpu trotzdem auf 100%
ich hab keine ahnung warum

hab warscheinlich irgendwo totalen Quark programmiert wo er kurzzeitig in ner Schleife festhängt..

aber das zu finden is nich sehr leicht..

http://dl.dropbox.com/u/14540512/MurphysDoodleJump.rar

Murphy
 
So, ich hab´ mich mal da umgesehen (keine Garantie, dass wirklich alles stimmt, was ich jetzt sage, weil ich jetzt auf die schnelle keinen Überblick hatte):

1. Du erstellst die ganze Zeit neue Plattformen (frisst Zeit) und löschst dabei nichtmal die Alten (frisst linear immer mehr Zeit).
Die beste Methode ist beim Programmstart einen gewissen Plattformbuffer zu erstellen, auf den dann immer zurückgegriffen wird. Den Buffer unterteilst du dann in 2 Listen: "used" und "unused". Soll jetzt oben eine neue Plattform erscheinen, benutzt du einfach eine "unused" Plattform, passt ihre Eigenschaften an und haust sie aus der "unused"-Liste raus und in die "used"-Liste wieder rein. Alle Interaktionen zwischen Plattform und Spielwelt und -ansicht sind dann auf die Plattformen in der "used"-Liste beschränkt. Dadurch wird immer gleich viel Speicher allokiert und die Performance bleibt in einem festen Bereich.

2. Randomizer sollte man nur so wenig wie möglich verwenden, die fressen auch gerne.

3. Für die Kollisionsüberprüfungen kannst du Rectangles verwenden. Die Methode "Intersect(Rectangle)" ist schon fest in XNA implementiert und daher wesentlich schneller und vor allem bequemer als die ganze Bedingungsjunglieraktion.

4. Du konvertierst bei den Properties zu viel (FirstValidPos usw.). Hier wird für jeden Zugriff neu konvertiert und in einem neuen Int32 abgespeichert. Viel einfacher ist es am Ende des Plattformupdates die Position einmalig als Int abzuspeichern. Kombiniert mit Punkt 3 wird dann idealerweise die Position des Rectangles dadurch korrigiert. Über Rectangle.X und .Y usw kannst du dann auf diese ganzzahligen Positionen zugreifen.

5. Verschiedene Kleinigkeiten (schwierige Steuerung, Plattformen die sich überschneiden) usw.
 
Zuletzt bearbeitet:
Weiß nich ob das immer noch so ist, aber als ich damals in DX 7 und 8 programmiert habe war es ganz normal das sich das programm dann 100% vom prozessor geholt hat, wurde mir zumindest damals in den suppport foren von MS berichtet. Sollte aber wieder was freigeben wenn ein Programm bedarf anmeldet. Aber wie gesagt das war früher, k.a. wie es heute aussieht.
 
Da das im Vollbild eine Echtzeitanwendung ist, wird dementsprechend soviel reserviert. Wie viel davon tatsächlich genutzt wird, weiß der Taskmanager natürlich nicht.
Man sollte bei den Taskmanagerangaben also grundsätzlich vorsichtig sein. Das sind keine genauen Werte! Vorallem nicht, wenn im Hintergrund die GC mitspielt.
 
XNA hat internen Timer der GameTime oder so heißt... bei jede verstrichene Gametime einheit wird alles neuberechnet. Das frist eben deine 100%... Bei XNA ist es auch so, dass du "mit deinem" spiel auch entsprechende resourcen reservierst. Damit du keine Lags während des spiels bekommst, läuft meist alles in Hintergrund was die CPU halt beanspruchst... ES WIRD NICHT ANGEHALTEN.... du kannst den internen GameTime anhalten und (noch garnicht selbst ausprobiert) gucken ob du immer noch 100% CPU Last hast. Damit dein spiel nicht lagt und co, müssen halt alle resoucen bereitgehalten werden.
 
Achso okay verstehe.
das ist gut zu wissen, Danke!


Murphy
 
roker002 schrieb:
Bei XNA ist es auch so, dass du "mit deinem" spiel auch entsprechende resourcen reservierst. Damit du keine Lags während des spiels bekommst, läuft meist alles in Hintergrund was die CPU halt beanspruchst...

Man kann keine CPU-Leistung "reservieren".
Man verbraucht einfach soviel wie man will, der Prozess-Scheduler des Betriebssystem versucht dann jedes Programm so oft ausführen zu lassen wie möglich (Scheduling-Verfahren) und erreicht somit, dass ein Programm zwar z.B. 100% der CPU-Last verbraten kann, aber trotzdem andere Programme zwischenzeitlich immer mal kurz laufen (Kontextwechsel).
 
@ice-breaker,
es ist klar, dass der Scheduler alle Prozesse verwaltet...

Also was ich eigentlich meinte... dass wenn du eine Endlosschleife programmierst die wirklich ohne Thread Sleep läuft, dann hast auch den gleichen Effekt.
 

Ähnliche Themen

Zurück
Oben