none
Überwachung des Speicherverbrauchs von Funktionen eines Objektes zur Laufzeit RRS feed

  • Frage

  • Ich habe eine C++ Applikation erstellt und diese mit dem integrierten Profiler von Visual Studio 2010 (mittels Instrumentation) analysiert. Wichtig waren hierbei die genauen Anteil der Funktionen an der Laufzeit (Beispielsweise die Angabe im Call-Tree dass die Funktion XY 100 Millisekunden benutzt wurde). Auf diese Weise konnte ich eine Auflistung aufstellen, welche mir zeigt wieviel Prozent der Zeit meine Applikation in den verschiedenen Bereichen verbrachte zb das 40 % der Zeit wurden im Rendering aufgewendet.

     

    Nun bräuchte ich ganz genau dasselbe, aber nicht für die Laufzeit, sondern für den Speicherverbrauch. Mich würde vor allem interessieren, wie hoch der durchschnittliche Speicherverbrauch im RAM, meiner KI ist.

    Nachdem ich nun schon lange auf der Suche bin und viele falschen Fährten verfolgte ein paar Einschränkungen:

    -Ich suche KEINE Tools oder Möglichkeiten um Memory Leaks oder Allokierungsfehler zu finden!

    -Tools die kostenpflichtig sind (wie zb Insure C++, Shiny, GlowCode, Purify etc) sind uninteressant. Geld kann ich dafür keines aufbringen.

    -Ich möchte einfach nur genau wissen, wieviel Speicher einzelne Funktonen innerhalb eines Objektes, zur Laufzeit benötigen.

    -Ich möchte KEINEN Pool für Allokierungen bauen, durch new Überladungen oder dergleichen. Das hilft mir ja nicht bei obiger Fragestellung.

    Wie gesagt ich bin schon sehr lange und verzweifelt auf der Suche und freue mich über jede Hilfe!

    Sonntag, 21. August 2011 20:46

Antworten

  • Solch ein Tool kenne ich nicht. Es würde auch nicht funktionieren, denn der Heap ist nun einmal global. Ein Destruktor mag in einem Teil eines Aufrufbaumes aufgerufen werden und ein Alloc in einem anderen.

    Man könnte Snapshots aus der Debug CRT instrumentalisieren.
    Siehe _CrtMmemCheckPoint, _CrtMemState, _CrtMemDumpStatistics, _CrtMemDumpAllObjects.

    Die MFC hat das ganze gekapselt.
    Siehe weiterleitende Artikel hier:
    http://msdn.microsoft.com/de-de/library/c99kz476.aspx#


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    Montag, 22. August 2011 06:08
    Moderator

Alle Antworten

  • Solch ein Tool kenne ich nicht. Es würde auch nicht funktionieren, denn der Heap ist nun einmal global. Ein Destruktor mag in einem Teil eines Aufrufbaumes aufgerufen werden und ein Alloc in einem anderen.

    Man könnte Snapshots aus der Debug CRT instrumentalisieren.
    Siehe _CrtMmemCheckPoint, _CrtMemState, _CrtMemDumpStatistics, _CrtMemDumpAllObjects.

    Die MFC hat das ganze gekapselt.
    Siehe weiterleitende Artikel hier:
    http://msdn.microsoft.com/de-de/library/c99kz476.aspx#


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    Montag, 22. August 2011 06:08
    Moderator
  • Zuerstmal danke für die Antwort!

     

    Nun gut, es gibt also keine Tools. Das hatte ich auch fast befürchtet.

     

    Ich hatte mit MFC bis jetzt noch überhaupt keinen Kontakt und kann das daher vielleicht nicht gut beurteilen können. Aber einerseits hat bereits die versuchte Verwendung von DEBUG_NEW zu vielen Fehlern geführt (afx.h beschwert sich dauernd das die Windows.h bereits inkludiert ist und das nicht sein darf, obwohl ich die gar nicht in meinem Code habe, wenn ich aber afx.h nicht inkludiere, wird DEBUG_NEW nicht erkannt), andererseits scheint mir die gezeigte Funktonalität auch nicht hilfreich für mich zu sein.

     

    Ich muss auch zugeben, generell in diesem Bereich kein Profi zu sein, weshalb ich meine Aufgabenstellung vielleicht auch falsch verstehe. Deshalb will ich etwas weiter ausholen, was den Grund meines Anliegens betrifft.

     

    Ich habe im Rahmen meiner Diplomarbeit, eine Simulation entwickelt welche eine spezielle Art von KI in den NPCs verwendet (was sie kann ist hierfür irrelevant). Dieselbe Simulation gibts auch ohne diese KI, in abgespeckter Form.

    Mit dem VS2010 Profiler habe ich wie bereits beschrieben, die Laufzeit auf meine Funktionsblöcke aufgeteilt und so die beiden Simulationen vergleichen. Mein Hauptziel ist es herauszufinden, wie groß der Aufwand der speziellen KI gegenüber der anderen ist.

    Meine Betreuer möchte nun von mir, das ich ihm auf die gleich Art und Weise, den Speicherverbrauch der Funktionsblöcke aufliste und in Diagramme packe. Deshalb nehme ich mal an, dass das auch irgendwie möglich sein wird. Er gab mir auch noch den Hinweis mit auf den Weg, dass diese Aufgabe mit einer Überladung des new Operators und 5 Zeilen Code machbar wäre.

    Was die Überladung betrifft konnte ich trotz mehrere Tag Recherche nichts finden. Ja klar, kann ich die Größe bei meinem Überladenen new Operator auslesen oder mit einem Placement new bestimmen wo die Objekte hinkommen. Aber das hilft mir ja nicht weiter. Die Größe meines KI-Objektes ist ja über die ganze Laufzeit hinweg beständig, ich allokiere dynamisch keinen Speicherplatz damit.

     

    Ich blicke da jedenfalls nicht mehr ganz durch. Also ich wäre auch Vorschlägen, wie ich das im Code selbst machen könnte ganz und gar nicht abgeneigt.

    Montag, 22. August 2011 10:51
  • 1. Du benötigst die MFC nicht. Die benutzt auch nur die CRT Klassen, die ich auch genannt habe.
    2. Du kannst mit den CRT Funktionen solche Snapshots erstellen und die Differenzen ausgeben lassen.
    3. Das Ganzeg eht ohne Probleme mit jeder Debug-Version, die die CRT benutzt, und nicht direkt Windows-Heap Funktionen oder VirtualAlloc.


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    Montag, 22. August 2011 11:04
    Moderator
  • Ich habe es letztlich doch hinbekommen die gezeigten Funktionen zu benutzen. Danke nochmal dafür ;)

     

    Da die Messungen aber ergeben (was ich sowieso vermutete), dass mein KI-Objekt sich zur Laufzeit am Heap nicht verändert, muss ich nun etwas anderes erledigen.

     

    Und zwar soll ich nun den Stack überwachen. Genauer gesagt müsste ich nun den Stack Frame meiner Funktionen messen, miteinander addieren und so auf den genutzten Stack meiner KI  zu kommen.

     

    Ich habe damit ebenfalls noch keinerlei Erfahrung. Habe mich mittlerweile etwas hineingelesen, habe aber noch keine richtig passende Lösung gefunden. Tools scheint es dafür ebenfalls wieder kaum brauchbare zugeben (zumindest keine frei verfügbaren). Gefunden habe ich bisher nur Möglichkeiten, um den gesamten Stack zu messen oder um die Stackobergrenze herauszufinden.

    Unter anderem auch CaptuereStackBackTrace http://msdn.microsoft.com/en-us/library/bb204633(v=vs.85).aspx. Allerdings tut auch das nicht wirklich was ich will, da ich ja nicht weiß hoch ich zurück gehen muss. Zudem gibt es auch nicht die Größe des Stackframes an.

     

    Ich würde gerne wissen ob es hierfür Funktionen gibt, die man eventuell innerhalb einer Funktion aufrufen kann und die Größe des Stack Frames zurückgibt.

     

    Bin natürlich auch für jeden anderen Vorschlag dankbar.

    Dienstag, 23. August 2011 16:19
  • Wenn es Dir gröber langt, kannst Du einfach die Größe des Speicherblockes erfragen, die der Stack belegt. Der Stack wächst automatisch druch eine Guardpage und schrumpft nie...

    Benutze einfach mit einer Adresse vom Stack VirtualQuery, dass sollte Dir die Infos über das Stack Segment geben.

    BTW: Jeder Thread hat einen eigenen Stack.


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    Dienstag, 23. August 2011 20:05
    Moderator