Jump'n'Run Performance Probleme



  • Hallo zusammen
    Ich benutze SDL seit einiger Zeit, jetzt hab ich mir ein Jump'n'Run geschrieben, das im Allgemeinen diese Struktur hat:

    int main
    {
      while (inMenu)  // solange man sich im Menu oder im Spiel befindet
      {
        while (inGame) // solange man direkt im Spiel ist
        {
           // Alles
        }
      }
    }
    

    Dort wo "Alles" steht, laufen die meisten Funktionen bezüglich des Spiels ab (ich hab auch Framerate Sachen dadrin).
    Nun tritt das Problem auf, dass das Spiel, wenn man vom Menu ins Spiel wechselt, am Anfang sehr schnell läuft, doch immer langsamer wird.
    Ich fürchte, mein Spiel pumpt den Arbeitsspeicher voll (ich hatte sogar schon Meldungen wegen der Auslagerungsdatei 😮 ). Beim Beenden des Spiels kann es je nach Spielzeit ewig gehen, bis mein PC wieder bedienbar ist... Ich hab übrigens 256MB RAM, sollte für so ein winziges Game eigentlich reichen.
    Ich kann nur nicht verstehen, wieso das passiert, ich erstelle ja nicht kontinuierlich neue Variabeln oder ähnliches, beim Ende einer Schleife wird der Speicher doch wieder freigegeben (also ausserhalb des Sichtbarkeitsbereiches einer Variable), oder hab ich mich hier total verschätzt?

    So nebenbei: Es ist schon gescheiter, wenn man immer innerhalb eines Blockes temporäre Variabeln deklariert als sie global zu deklarieren und immer wieder zu überschreiben? Ich mein z.B. temporäre SDL_Rects oder Integer oder ähnliches...

    Es ist einfach mühsam, so kann man sich nur kurze Spiele erlauben 🙄
    Ich wäre froh, wenn ihr Vorschläge hättet, denn was Performance betrifft, bin ich ein Obern00b 😃



  • Also rein intuitiv würde ich mal sagen, du forderst in der Schleife irgendwoe Speicher an (new) den du nicht mehr freigibst.

    Der Speicher von Stack - Variablen sollte auf jeden Fall ordnungsgemäß freigegeben werden (uU recycelt wenn der Compiler der Meinung war)



  • Ich pflichte da Darth bei, du forderst in den Schleifen Speicher an (mit new) den du nicht wieder freigibst (mit delete)... Check mal die Schleifen durch.

    Aber was anderes am Rande:

    int main()
    {
      while(GameRunning)
      { 
          if (inGame)
          {
          }
          if (inMenu)
          {
          }
      }
    }
    

    Ich würds eher so designen. Ich finde das generell besser, nur eine while-Schleife in der Main zu haben und nicht geschachtelte... aber jedem das seine :D.
    rya.



  • Variablen ala so:

    // ...
    while (...)
    {
        int x;
        Rect r;
    }
    

    sind egal.
    Was zu Leaks führen kann sind dinge die dynamisch angefordert werden. Also wenn du z.B. sowas hast:

    // ...
    while (...)
    {
        Foo f = LoadFooFromFile("...");
    }
    

    Bei sowas kommt es darauf an was "Foo" ist. Ist "Foo" ein "Handle", dann muss es normalerweise wieder freigegeben werden:

    while (...)
    {
        Foo f = LoadFooFromFile("...");
        // ...
        ReleaseFoo(f);
    }
    

    Bei solchen Dinge wäre es meist auch schlauer die 1x vor der Spiel-Schleife anzufordern und erst danach wieder freizugeben:

    Foo f = LoadFooFromFile("...");
    while (...)
    {
        // ...
    }
    ReleaseFoo(f);
    


  • Falls du Visual Studio verwendest kannst du mal den Visual Leak Detector (http://dmoulding.googlepages.com/vld) ausprobieren.

    schirrmie



  • Hallo!

    Ich denke auch dass Du ein Speicherleck hast, Du kannst neben dem Tool das schirrmie grad gezeigt hat auch mal den AMD CodeAnalyzer drüberlaufen lassen. Dann weisst Du wo dein Programm am meisten Rechenzeit reinsteckt.

    @schirrmie

    Danke für den Link, habe sowas gesucht. Habe grad mal über meine Engine laufen lassen, die ich schon seit ner weile entwickle und freue mich über die Meldung:

    No memory leaks detected.

    🙂

    Gruss, Andi



  • Ja finde den Satz auch immer wieder toll 😉

    schirrmie



  • Das mit dem new und delete könnte durchaus sein. Aber was du mit ReleaseFoo meinst, begreife ich nicht ganz... Ich hab zwar Dateiladungs- und Speicherungsfunktionen, bin mir aber nicht sicher, ob du das gemeint hast... Oder beziehst du dich z.B. auf SDL_LoadBMP("..."), eine Bitmap-Ladungsfunktion? (sry für meine "Unahnung" :))
    Trotzdem vielen Dank für die schnellen Antworten!

    LG, Nexus



  • SDL_Surface *SDL_LoadBMP(const char *file);
    

    ?

    Wenn du das Surface nicht mehr benötigst musst du es los werden. Warscheinlich per delete



  • Aha ok, vielen Dank... Nein, das wäre wohl eher folgende Funktion:

    SDL_FreeSurface(SDL_Surface *Surface);
    


  • Ich meinte mit "ReleaseFoo" einfach "die passende Freigebe-Funktion" 🙂
    "ReleaseFoo" steht in dem Fall für SDL_FreeSurface:

    void foo()
    {
        // Bild laden (erzeugt eine neue Surface, einen Zeiger darauf speichern wir in "image")
        SDL_Surface* image = SDL_LoadBMP("c:\\test.bmp");
    
        // ...
        // image verwenden
        // ...
    
        SDL_FreeSurface(image); // image freigeben
    }
    

    Wenn die SDL_FreeSurface Zeile fehlt wird das Bild nicht freigegeben, und du hast ein Speicher-Leak.

    BTW: SDL Duko: http://docs.mandragor.org/files/Common_libs_documentation/SDL/SDL_Documentation_project_en/



  • schirrmie schrieb:

    Falls du Visual Studio verwendest kannst du mal den Visual Leak Detector (http://dmoulding.googlepages.com/vld) ausprobieren.

    schirrmie

    Und noch ein Danke! Seit bei mir Visual C++ komischerweise mit _crtSetDbgFlag(..) nicht mehr die Leaks reported, hab ich mir schon Gedanken gemacht :D. Das Programm ist richtig gut...
    Sorry für Offtopic 🙂
    rya.


Anmelden zum Antworten